{"record":{"id":"08b6f5e134cfba44","repo":"jdx/mise","slug":"inline-content","errorCode":null,"errorMessage":"inline content","messagePattern":"inline content","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/oci/builder.rs","lineNumber":918,"sourceCode":"                        file::read(entry.path())?,\n                        source_mode(entry.path())?,\n                    )?;\n                }\n            }\n            FileMode::Template => {\n                let rendered = crate::system::files::render_template(cfg, req)?;\n                entries.add_file(\n                    oci_target_path(req)?,\n                    rendered.into_bytes(),\n                    source_mode(&req.source)?,\n                )?;\n            }\n            FileMode::Content => {\n                entries.add_file(\n                    oci_target_path(req)?,\n                    req.content\n                        .as_deref()\n                        .expect(\"inline content\")\n                        .as_bytes()\n                        .to_vec(),\n                    0o600,\n                )?;\n            }\n        }\n    }\n\n    info!(\"oci: adding {} [dotfiles] entries\", requests.len());\n    let (files, dirs) = entries.into_layer_inputs();\n    layer::build_layer_from_files_and_dirs(&files, &dirs, owner)\n}\n\nfn collect_source_as_files(\n    source: &std::path::Path,\n    target: &str,\n    entries: &mut DotfilesLayerEntries,\n) -> Result<()> {","sourceCodeStart":900,"sourceCodeEnd":936,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/oci/builder.rs#L900-L936","documentation":"When building the OCI dotfiles layer, a FileMode::Content entry writes its inline payload; this expect fires if planning produced a Content-mode FileRequest with content = None. Request construction in src/system/files.rs sets mode Content and content together (line 271), so the panic indicates either an internal wiring bug or library misuse when callers assemble [dotfiles] requests by hand.","triggerScenarios":"Running an OCI image build with a [dotfiles] entry that ends up in content mode without a content value — e.g. a code path or API caller that sets mode = content but never attaches the inline string.","commonSituations":"Hand-constructed FileRequest usage against mise's OCI builder APIs; regressions after changes to [dotfiles] planning; misconfigured [dotfiles] entries combined with template rendering paths.","solutions":["Give the entry an explicit content = \"...\" value, or switch it to a source-based mode (copy/symlink)","If the config looks valid, update mise and report the panic — the planner should never emit content-mode without content"],"exampleFix":"# before (mise.toml)\n[dotfiles.motd]\nmode = \"content\"\n# content missing\n\n# after\n[dotfiles.motd]\nmode = \"content\"\ncontent = \"welcome aboard\"","handlingStrategy":"validation","validationCode":"# Validate [dotfiles] content-mode entries before an OCI build\npython3 - <<'PY'\nimport sys, tomllib\nwith open('mise.toml', 'rb') as fh:\n    cfg = tomllib.load(fh)\nfor name, spec in (cfg.get('dotfiles') or {}).items():\n    if spec.get('mode') == 'content' and not spec.get('content'):\n        sys.exit(f'[dotfiles].{name!r}: mode=content requires a content value')\nPY","typeGuard":"fn has_inline_content(req: &FileRequest) -> bool {\n    match req.mode {\n        FileMode::Content => req.content.is_some(),\n        _ => true,\n    }\n}","tryCatchPattern":null,"preventionTips":["Always pair mode = \"content\" with an explicit content string in [dotfiles] entries","When building FileRequest values programmatically, assert the mode/content pairing before invoking the OCI builder"],"tags":["panic","oci","dotfiles","config","invariant"],"backgroundTag":"missing-required-config-field","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}