jdx/mise · error

"{path_raw}".{id}: line may not contain a newline; use a blo

Error message

"{path_raw}".{id}: line may not contain a newline; use a block for multi-line content, ignoring entry

What it means

Line-based edits match against individual lines of the target file, so a `line` value containing an embedded newline could never converge on a stable match. resolve_entry raises this error and ignores the entry; multi-line managed content must use `block` instead.

Source

Thrown at src/system/edits.rs:352

                        "\"{path_raw}\".{id}: unknown template engine '{other}' (expected \"tera\"), ignoring entry"
                    )
                }
            };
            let comment = entry
                .comment
                .unwrap_or_else(|| infer_comment(&path).to_string());
            EditOp::Block {
                source,
                template,
                comment,
            }
        }
        (false, Some(line)) => {
            // a "line" is matched against the file's individual lines, so an
            // embedded newline could never converge — use a block for
            // multi-line content
            if line.contains('\n') {
                bail!(
                    "\"{path_raw}\".{id}: line may not contain a newline; use a block for multi-line content, ignoring entry"
                )
            }
            let position = match entry.position.as_deref() {
                None | Some("append") => LinePosition::Append,
                Some("prepend") => LinePosition::Prepend,
                Some(other) => {
                    bail!(
                        "\"{path_raw}\".{id}: unknown line position '{other}' (expected \"append\" or \"prepend\"), ignoring entry"
                    )
                }
            };
            EditOp::Line {
                line: line.clone(),
                position,
            }
        }
    };

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Rename the field from `line` to `block` and keep the multi-line content.
  2. Split the content into multiple entries, one per line, with distinct ids.
  3. Strip or escape the newline if a single logical line was intended.

Example fix

// before
[[dotfiles]]
id = "aliases"
path = "~/.zshrc"
line = """alias gs='git status'
alias gl='git log'"""

// after
[[dotfiles]]
id = "aliases"
path = "~/.zshrc"
block = """alias gs='git status'
alias gl='git log'"""
Defensive patterns

Strategy: validation

Validate before calling

if let Some(line) = &entry.line {
    assert!(!line.contains('\n'), "entry {}: line must be a single line; use block for multi-line", entry.id);
}

Prevention

When it happens

Trigger: A [dotfiles] entry has `line = "first\nsecond"` (a literal newline inside the line string), typically from a multi-line TOML string or interpolated content.

Common situations: Pasting a multi-line snippet into a line field; building the line value dynamically (e.g. via Tera) where the rendered result contains newlines; copy-paste mistakes between block and line.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/d4022a0a357f8d04. Report an issue: GitHub.