AprilNEA/OpenLogi · error
--id must be one synthetic path component without separators
Error message
--id must be one synthetic path component without separators
What it means
The contribute command requires `--id` to be exactly one path component with no separators. It checks `Path::file_name()` round-trips to the whole value and rejects any `/` or `\\`. This prevents the synthetic fixture output from escaping or nesting outside its intended directory (path-traversal / nested-path ids).
Solutions
- Use a single name without separators, e.g. `--id my-device` instead of `--id devices/my-device`.
- If you need hierarchy, run the command with `--output /base/my-device` and keep the id as just `my-device` (the output's last component must equal the id anyway).
- Sanitize the id before calling: replace `/` and `\\` with `-` or reject it in your wrapper script.
Example fix
// before openlogi fixture contribute --id devices/mx-master --name "MX Master" --output fixtures/devices/mx-master // after openlogi fixture contribute --id mx-master --name "MX Master" --output fixtures/devices/mx-master
Defensive patterns
Strategy: validation
Validate before calling
case "$ID" in */*|\\\\*) echo "--id must be one path component" >&2; exit 1;; esac [ "$(basename "$ID")" = "$ID" ] || exit 1
Prevention
- Keep ids as bare slugs (letters, digits, dashes); never build them by joining paths.
- Put path structure only in --output, whose last component must equal the id.
- Sanitize inputs from spreadsheets/CSVs that may carry slashes.
When it happens
Trigger: Pass `--id` containing `/` (e.g. `a/b`), a backslash (`a\\b`), an absolute path (`/tmp/x`), a trailing slash (`x/`), or `..`-tricks (`a/../b`) — anything where `Path::new(id).file_name() != Some(id)` or separators are present.
Common situations: Copy-pasting a full path into `--id` instead of only the directory name, Windows-style separators typed on Linux/macOS, or building ids by joining segments.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- saved contribution profile does not match its resumable…
- --id must be a nonempty synthetic path component
- --name must be a nonempty synthetic device name
- --output directory name must exactly equal --id
- --id and --name must match the in-progress contribution
AI-assisted analysis of AprilNEA/OpenLogi@e846e6f4b4 (2026-09-13).
Data as JSON: /api/errors/c6499ec0fe43b6f6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/openlogi-cli/src/cmd/fixture/contribute.rs:453
if matches {
Ok(())
} else {
bail!(
"the selected direct-capture target does not match the profile transport and slot; \
reconnect the same device and use the same --device selector"
)
}
}
fn validate_args(args: &ContributeArgs) -> Result<()> {
if args.id.trim().is_empty() || matches!(args.id.as_str(), "." | "..") {
bail!("--id must be a nonempty synthetic path component");
}
if Path::new(&args.id).file_name() != Some(OsStr::new(&args.id))
|| args.id.contains('/')
|| args.id.contains('\\')
{
bail!("--id must be one synthetic path component without separators");
}
if args.name.trim().is_empty() {
bail!("--name must be a nonempty synthetic device name");
}
if args.output.file_name() != Some(OsStr::new(&args.id)) {
bail!("--output directory name must exactly equal --id");
}
Ok(())
}
fn validate_state(args: &ContributeArgs, state: &ContributionState) -> Result<()> {
if state.version != STATE_VERSION {
bail!("unsupported contribution state version {}", state.version);
}
if state.fixture_id != args.id
|| state.profile_id != format!("{}-profile", args.id)
|| state.profile_name != args.name
{View on GitHub (pinned to e846e6f4b4)