multica-ai/multica · error
fixed_args entries cannot contain NUL bytes
Error message
fixed_args entries cannot contain NUL bytes
What it means
marshalFixedArgs rejects fixed_args entries containing the NUL byte (\x00). Go strings can hold NUL, but OS exec argv is C-string terminated, so a NUL inside an argument would silently truncate the flag at exec time. The check exists to fail fast at the API boundary instead of corrupting the spawned command line.
Solutions
- Sanitize entries: a.replace(/\x00/g, "") or reject at the client with a clear message
- Verify the source of the args is text (decode as UTF-8 and validate) before building the payload
- If you actually need to pass a NUL-containing value, that is impossible via argv — redesign to pass a file path or env var
Example fix
// before
fixedArgs: buffer.toString("utf8").split("\n")
// after
fixedArgs: buffer.toString("utf8").split("\n").map(s => s.replace(/\x00/g, "")).filter(Boolean) Defensive patterns
Strategy: validation
Validate before calling
const hasNul = (s: string) => s.includes('\x00');
const safeArgs = fixedArgs.map(a => a.replace(/\x00/g, ''));
if (fixedArgs.some(hasNul)) log.warn('NUL bytes stripped from fixed_args'); Type guard
function isNulFree(s: string): boolean { return !s.includes('\x00'); } Prevention
- Treat NUL in argv-destined strings as producer corruption — investigate the source
- Validate config text is valid UTF-8 without NUL at ingestion
- NUL cannot be passed through argv at all; redesign around files or env vars
When it happens
Trigger: POST/PUT a runtime profile whose fixed_args contains a literal \u0000 — usually binary data, a protocol frame, or a string built from a buffer that was not validated as UTF-8 text.
Common situations: Reading args from a binary config or message queue into strings; fuzzing tools injecting NUL; encoding mishaps where UCS-4/UTF-32 text is decoded per-byte leaving NULs between characters.
Related errors
- command_name cannot contain NUL bytes
- command_name is required
- command_name must be a single executable token; put…
- empty expected checksum for
- fixed_args entries must be non-empty
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/21637055f7440c20.
Report an issue: GitHub.
Appendix: source
Thrown at server/internal/handler/runtime_profile.go:96
// visibility control only once those read paths enforce creator visibility.
// Follow-up: MUL-3308.
const runtimeProfileDefaultVisibility = "workspace"
// marshalFixedArgs validates and JSON-encodes the fixed_args list. Each entry
// must be a non-empty string; the column defaults to an empty array.
func marshalFixedArgs(args []string) ([]byte, error) {
if len(args) == 0 {
return []byte("[]"), nil
}
clean := make([]string, 0, len(args))
for _, a := range args {
// fixed_args are launch flags inherited by every agent on the runtime;
// blank entries are always a client mistake.
if strings.TrimSpace(a) == "" {
return nil, errors.New("fixed_args entries must be non-empty")
}
if strings.ContainsRune(a, '\x00') {
return nil, errors.New("fixed_args entries cannot contain NUL bytes")
}
clean = append(clean, a)
}
return json.Marshal(clean)
}
func validateRuntimeProfileCommandName(commandName string) error {
if commandName == "" {
return errors.New("command_name is required")
}
if strings.ContainsAny(commandName, " \t\r\n") {
return errors.New("command_name must be a single executable token; put arguments in fixed_args")
}
if strings.ContainsRune(commandName, '\x00') {
return errors.New("command_name cannot contain NUL bytes")
}
return nil
}View on GitHub (pinned to 2c0912b6ec)