Guide
Path canonicalisation rules — the core keeps writes in bounds
What target_path you can pass to `upload.create_link` and `upload.write`. Why the rules are strict — no project can escape its own prefix — and how to work around them.
5/18/2026 · connect0 · 2 min
Every path is canonicalised at the core, so no write can escape the project prefix the system controls.
Every upload tool runs the target_path through the same canonicalisation function. The rules are deliberately narrow:
| Rule | Why |
|---|---|
Must be relative (no leading /). | The projects/<id>/ prefix is server-controlled; you can't escape it. |
No .. segments. | Traversal would let one project write under another's prefix. |
No segment starts with . | Reserves .git, .env, .cache, etc. for our future use. |
Characters in [A-Za-z0-9._-/] only. | Easy to validate, easy to interpolate into shell, easy to log. |
| ≤ 256 chars. | R2 key length cap with headroom. |
Examples
Accepted:
foo.txtdata/sales.csvnested/deeper/and-deeper/file.json2026-Q1/report-final_v2.pdf
Rejected:
/foo— leading slash.../etc/passwd—..segment.foo/../bar—..segment..git/HEAD— segment starts with..foo/.env— same.My File.csv— space.report?.pdf— query-string character.foo/— empty segment.
Filename sanitisation in the dashboard
The dashboard drag-drop UI doesn't reject files with bad characters — it sanitises them. Sales Q1 / 2026.csv becomes Sales_Q1___2026.csv automatically. The MCP tools don't sanitise; they reject. This is intentional: the dashboard is for humans who want it to "just work," MCP is for agents that should pass canonicalised paths in the first place.
What if I need a space in my filename?
You don't. Spaces in filenames have a long history of breaking things — shell escaping bugs, URL encoding bugs, audit-log parsing bugs. Use _ or -. Every tool that touches the filesystem will thank you.
What if my filename has Unicode?
Same answer — ASCII subset only. We're aware this is restrictive for non-Latin alphabets. If it becomes a real complaint we'll add a relaxed mode behind a flag, but the current [A-Za-z0-9._-/] is the defensible default.
How to work around the rules
- Generated from a user-supplied name. Strip / replace before passing. Same logic the dashboard uses:
name.replace(/[^A-Za-z0-9._-]/g, '_'). - Need a hidden-config-style file. Drop the leading
.and have the agent rename inside the sandbox viash "mv /workspace/env /workspace/.env". The path inside the sandbox isn't subject to the canonicalisation rules — only the upload key is.
Next steps
Where this fits
This is the One system of record pillar of connect0 — the core that connects everything your company runs on. The core owns the projects/<id>/ prefix and canonicalises every path against it, so isolation between projects is enforced by the system, not left to the caller. Start building → · All guides →