Nice — your Python build ran successfully. The failure is now purely a Cloudflare Pages output validation issue:
“build output directory contains links to files that can’t be accessed”
That error almost always means: your generated HTML contains absolute file paths or references to files outside the published output directory (or references files that simply aren’t in the output dir).
From your log I see this suspicious line:
Copied static assets from /opt/buildhome/repo/generator/static to assets
…and it copied to assets (relative), but we don’t know where that “assets” folder lives (repo root? output dir?).
Cloudflare Pages only publishes what’s inside your configured output directory (e.g. dist/). During validation it crawls your HTML/CSS and checks that linked files exist inside that output folder.
So the fix is: ensure every referenced file path resolves inside your output directory.
In your build script, define an explicit OUT_DIR and always write/copy into it.
Example:
OUT_DIR = REPO_ROOT / "dist"
ASSETS_OUT = OUT_DIR / "assets"
ASSETS_OUT.mkdir(parents=True, exist_ok=True)
shutil.copytree(STATIC_DIR, ASSETS_OUT, dirs_exist_ok=True)
If you currently do something like:
…that will put assets in the current working directory, not necessarily in dist/.
Cloudflare will fail if HTML points to /assets/... but dist/assets/... doesn’t exist.
If any of your templates accidentally include:
/opt/buildhome/repo/...
file:///...
- or Windows paths like
C:\...
Cloudflare will complain because those “links” can’t exist in the deployed site.
Search your output for /opt/buildhome:
grep -R "/opt/buildhome" -n dist || true
If you see it, it’s coming from a template variable like content_root being used to build URLs.
Rule: filesystem paths are for reading files; URLs should be relative like /assets/foo.css or assets/foo.css.
If you deploy at the domain root (e.g. uncharted-limbo.com), /assets/x.css is fine.
But if you’re previewing under a Pages subpath or GitHub Pages project path, root-relative paths can break.
The safest static-site pattern is:
- keep HTML links as
/assets/... (root-relative) if site is always at domain root
- otherwise use relative links (
assets/...) or a configurable SITE_BASEURL
Since you came from GitHub Pages, you might have mixed base URL logic.
Your script copied static assets to assets but Cloudflare expects them in dist/assets.
So do this:
- Ensure output directory is
dist
- Ensure all writes/copies target
dist/**
If you currently have something like:
shutil.copytree(static_src, "assets", dirs_exist_ok=True)
Change to:
shutil.copytree(static_src, OUT_DIR / "assets", dirs_exist_ok=True)
And make sure the HTML links use /assets/... or assets/... consistently with what you copied.
In Cloudflare, add a temporary line at the end of your build command:
If you don’t see dist/assets/..., that’s the smoking gun.
To give you the exact fix in your script, paste either:
- the part where you set the output directory + where you copy
static, or
- the repo tree of your output folder (
dist/) after a local build.
But 90% chance the fix is simply: copy static into the output directory, not into repo root, and ensure your generated links match that.
If you paste just the snippet around the “Copied static assets…” line in your Python code, I’ll rewrite it correctly.