Skip to content

Commit 5f0186b

Browse files
hasip-timurtaspetebacondarwin
authored andcommitted
fix: resolve 'Failed to parse URL from /me' error in container dry-run deployments
- Always call fillOpenAPIConfiguration when containers are defined, even in dry-run mode - Set up OpenAPI configuration before calling maybeBuildContainer in the main deploy flow - Add test to ensure container dry-run works without URL parsing errors - Add changeset for this bugfix This fixes the issue where 'wrangler deploy --dry-run' with containers using local Dockerfiles would fail because OpenAPI configuration wasn't set up before making API calls during container building. The fix ensures that the AccountService.getMe() call in loadAccount() has a proper base URL configured instead of an empty string, preventing the invalid '/me' URL error.
1 parent 2ee8c4a commit 5f0186b

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed

.changeset/fine-cars-enter.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
fix: resolve "Failed to parse URL from /me" error in container dry-run deployments
6+
7+
Fixes an issue where `wrangler deploy --dry-run` with containers using local Dockerfiles would fail with "Failed to parse URL from /me" error. The fix ensures OpenAPI configuration is properly set up before making API calls during container building in dry-run mode.
8+
9+
This change only affects the specific error scenario and maintains backward compatibility.

packages/wrangler/src/__tests__/deploy.test.ts

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11084,6 +11084,159 @@ export default{
1108411084
}
1108511085
`);
1108611086
});
11087+
11088+
it("should not fail with 'Failed to parse URL from /me' error when using containers with Dockerfile in dry-run", async () => {
11089+
// This test ensures that the fix for the container dry-run URL parsing error works
11090+
// Previously, dry-run with containers + Dockerfile would fail with "Failed to parse URL from /me"
11091+
// because OpenAPI configuration wasn't set up before making API calls during container building
11092+
11093+
// Set up Docker binary path (required for container tests)
11094+
vi.stubEnv("WRANGLER_DOCKER_BIN", "/usr/bin/docker");
11095+
11096+
// Mock Docker commands that would be called during container building
11097+
function defaultChildProcess() {
11098+
return {
11099+
stderr: Buffer.from([]),
11100+
stdout: Buffer.from("i promise I am a successful process"),
11101+
on: function (reason: string, cbPassed: (code: number) => unknown) {
11102+
if (reason === "close") {
11103+
cbPassed(0);
11104+
}
11105+
return this;
11106+
},
11107+
} as unknown as ChildProcess;
11108+
}
11109+
11110+
vi.mocked(spawn)
11111+
// Mock docker info command
11112+
.mockImplementationOnce((cmd, args) => {
11113+
expect(cmd).toBe("/usr/bin/docker");
11114+
expect(args).toEqual(["info"]);
11115+
return defaultChildProcess();
11116+
})
11117+
// Mock docker build command
11118+
.mockImplementationOnce((cmd, args) => {
11119+
expect(cmd).toBe("/usr/bin/docker");
11120+
// In dry-run mode, we expect docker build to be called but not push
11121+
expect(args[0]).toBe("build");
11122+
let dockerfile = "";
11123+
const readable = new Writable({
11124+
write(chunk) {
11125+
dockerfile += chunk;
11126+
},
11127+
final() {},
11128+
});
11129+
return {
11130+
pid: -1,
11131+
error: undefined,
11132+
stderr: Buffer.from([]),
11133+
stdout: Buffer.from("i promise I am a successful docker build"),
11134+
stdin: readable,
11135+
status: 0,
11136+
signal: null,
11137+
output: [null],
11138+
on: (reason: string, cbPassed: (code: number) => unknown) => {
11139+
if (reason === "exit") {
11140+
expect(dockerfile).toEqual(
11141+
"FROM node:18-alpine\nCMD echo 'test'"
11142+
);
11143+
cbPassed(0);
11144+
}
11145+
},
11146+
} as unknown as ChildProcess;
11147+
})
11148+
// Mock docker image inspect command
11149+
.mockImplementationOnce((cmd, args) => {
11150+
expect(cmd).toBe("/usr/bin/docker");
11151+
expect(args[0]).toBe("image");
11152+
expect(args[1]).toBe("inspect");
11153+
11154+
const stdout = new PassThrough();
11155+
const stderr = new PassThrough();
11156+
11157+
const child = {
11158+
stdout,
11159+
stderr,
11160+
on(event: string, cb: (code: number) => void) {
11161+
if (event === "close") {
11162+
setImmediate(() => cb(0));
11163+
}
11164+
return this;
11165+
},
11166+
};
11167+
11168+
// Simulate docker image inspect output
11169+
setImmediate(() => {
11170+
stdout.emit("data", `123456 4 []`);
11171+
});
11172+
11173+
return child as unknown as ChildProcess;
11174+
});
11175+
11176+
writeWranglerConfig({
11177+
durable_objects: {
11178+
bindings: [
11179+
{
11180+
name: "CONTAINER_BINDING",
11181+
class_name: "TestContainer",
11182+
},
11183+
],
11184+
},
11185+
containers: [
11186+
{
11187+
name: "test-container",
11188+
class_name: "TestContainer",
11189+
image: "./Dockerfile", // This is the key - local Dockerfile that triggers the build
11190+
max_instances: 10,
11191+
},
11192+
],
11193+
migrations: [{ tag: "v1", new_sqlite_classes: ["TestContainer"] }],
11194+
});
11195+
11196+
fs.writeFileSync(
11197+
"index.js",
11198+
`export class TestContainer {}; export default {
11199+
async fetch(request) {
11200+
return new Response('Hello from container!');
11201+
},
11202+
};`
11203+
);
11204+
11205+
// Create a simple Dockerfile
11206+
fs.writeFileSync("Dockerfile", "FROM node:18-alpine\nCMD echo 'test'");
11207+
11208+
// Mock the necessary CloudChamber account API calls
11209+
const { mockAccountV4 } = await import("./cloudchamber/utils");
11210+
mockAccountV4(["containers:write"]);
11211+
11212+
// Also mock the CloudChamber account endpoint specifically that loadAccount() calls
11213+
msw.use(
11214+
http.get(
11215+
"*/accounts/:accountId/cloudchamber/account",
11216+
() => {
11217+
return HttpResponse.json({
11218+
success: true,
11219+
result: {
11220+
external_account_id: "test-account-id",
11221+
account_tag: "test-account",
11222+
locations: [],
11223+
limits: {
11224+
disk_mb_per_deployment: 2000,
11225+
},
11226+
},
11227+
});
11228+
},
11229+
{ once: true }
11230+
)
11231+
);
11232+
11233+
// This should NOT fail with "Failed to parse URL from /me" error
11234+
// The fix ensures OpenAPI configuration is set up before container building in dry-run
11235+
await runWrangler("deploy index.js --dry-run");
11236+
11237+
expect(std.out).toContain("--dry-run: exiting now.");
11238+
expect(std.err).not.toContain("Failed to parse URL from /me");
11239+
});
1108711240
});
1108811241

1108911242
describe("--node-compat", () => {

0 commit comments

Comments
 (0)