Skip to content

Commit 4ccb4cc

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 3442a1f commit 4ccb4cc

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

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

0 commit comments

Comments
 (0)