xai-org/grok-build · error
deny glob {glob:?}: empty path segment (a doubled '//' or tr
Error message
deny glob {glob:?}: empty path segment (a doubled '//' or trailing '/'); remove the extra slash in sandbox.toml What it means
validate_deny_glob rejects deny globs containing empty path segments — doubled slashes (`a//b`) or trailing slashes (`a/`) — because globset keeps `//` literal while the macOS regex collapses it, causing cross-platform divergence. Only a single leading `/` (absolute-path anchor) is permitted to be an 'empty' segment.
Source
Thrown at crates/codegen/xai-grok-sandbox/src/deny/glob.rs:92
/// 2. Compile through `globset` (the Linux matcher) so a malformed glob (`a**b`,
/// unterminated `[`) fails closed identically on both platforms.
#[cfg(all(feature = "enforce", unix))]
pub(crate) fn validate_deny_glob(glob: &str) -> anyhow::Result<()> {
if let Some(c) = glob.chars().find(|&c| matches!(c, '{' | '}' | '\\')) {
anyhow::bail!(
"deny glob {glob:?} uses unsupported metacharacter '{c}' \
(brace alternation and backslash-escapes are not supported; \
use separate deny entries)"
);
}
// `**` must be a whole path component (gitignore semantics). A non-component
// `**` (e.g. `a**b`) would translate to `.*` on macOS but collapse to `*` in
// globset — reject it on both platforms so they never diverge. Empty
// segments (`a//*`) drift the same way: globset keeps `//` literally while
// the macOS regex collapses it.
for (index, segment) in glob.split('/').enumerate() {
if segment.is_empty() && !(index == 0 && glob.starts_with('/')) {
anyhow::bail!(
"deny glob {glob:?}: empty path segment (a doubled '//' or \
trailing '/'); remove the extra slash in sandbox.toml"
);
}
// `.`/`..` would let a relative glob scan outside the workspace on
// Linux while the macOS regex stays dead; reject on both platforms.
if segment == "." || segment == ".." {
anyhow::bail!(
"deny glob {glob:?}: `.` and `..` segments are not supported; \
write the path without them (use an absolute path to deny \
files outside the workspace)"
);
}
if segment.contains("**") && segment != "**" {
anyhow::bail!(
"deny glob {glob:?}: `**` must be its own path segment (got {segment:?}); \
write it as `**/` or `/**`, e.g. `a/**/b`"
);View on GitHub (pinned to bc7f02eddd)
Solutions
- Remove the doubled or trailing slash from the glob in sandbox.toml.
- If generating globs programmatically, join path components with a normalizing joiner that collapses separators.
- Keep an optional single leading `/` for absolute globs — that is the only allowed empty segment.
Example fix
// before (sandbox.toml) deny = ["/tmp//secrets/**", "var/log/"] // after deny = ["/tmp/secrets/**", "var/log"]
Defensive patterns
Strategy: validation
Validate before calling
fn deny_glob_segments_ok(glob: &str) -> bool {
glob.split('/').enumerate().all(|(i, seg)| {
!seg.is_empty() || (i == 0 && glob.starts_with('/'))
})
}
for g in &deny_globs {
assert!(deny_glob_segments_ok(g), "empty path segment in deny glob: {g}");
} Prevention
- Normalize generated paths before writing them into sandbox.toml (collapse `//`, strip trailing `/`).
- Keep a single leading `/` only for absolute-path globs.
- Lint sandbox.toml deny entries for doubled/trailing slashes in CI.
When it happens
Trigger: A deny glob in sandbox.toml such as `/tmp//x`, `foo/bar/`, or any string where glob.split('/') yields an empty segment that is not the leading absolute-path position.
Common situations: Concatenating path strings in config generation (prefix + `/` + path where path already starts with `/`); hand-edited globs with trailing slashes; template rendering producing doubled separators.
Related errors
- deny glob {glob:?} uses unsupported metacharacter '{c}' (bra
- invalid deny glob {glob:?}: {e}
- Custom sandbox profile '{name}' not found. Define it in ~/.g
- no target specified
- Invalid GCS URL scheme: expected 'gs', got '{}'
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/b2bf161e7d7e803d.
Report an issue: GitHub.