jdx/mise · error

{} contains `{TASK_PLACEHOLDER_START}` but no `{TASK_PLACEHO

Error message

{} contains `{TASK_PLACEHOLDER_START}` but no `{TASK_PLACEHOLDER_END}` after it, --inject requires both markers

What it means

`mise generate task-docs --inject` requires both markers, with the end marker after the start marker. When the file contains TASK_PLACEHOLDER_START but no TASK_PLACEHOLDER_END after it, mise bails rather than replacing to end-of-file, because it cannot determine where the injected block should stop.

Source

Thrown at src/cli/generate/task_docs.rs:155

/// Replace everything between the mise-tasks markers in `contents` with `doc`.
///
/// Both markers must be present, with the end marker after the start marker. When
/// a marker is missing this errors instead of writing anything: falling back to
/// "the block starts at byte 0" truncated files that had no markers at all, and
/// panicked outright on files shorter than the marker (discussions/4676).
fn inject_task_docs(contents: &str, doc: &str, output: &Path) -> eyre::Result<String> {
    let Some(start) = contents.find(TASK_PLACEHOLDER_START) else {
        bail!(
            "{} does not contain the `{TASK_PLACEHOLDER_START}` marker required by --inject, add:\n\n{TASK_PLACEHOLDER_START}\n{TASK_PLACEHOLDER_END}",
            file::display_path(output)
        );
    };
    let body_start = start + TASK_PLACEHOLDER_START.len();
    let Some(end) = contents[body_start..]
        .find(TASK_PLACEHOLDER_END)
        .map(|e| e + body_start)
    else {
        bail!(
            "{} contains `{TASK_PLACEHOLDER_START}` but no `{TASK_PLACEHOLDER_END}` after it, --inject requires both markers",
            file::display_path(output)
        );
    };
    let mut contents = contents.to_string();
    contents.replace_range(body_start..end, doc);
    Ok(contents)
}

#[cfg(test)]
mod tests {
    use super::{TASK_PLACEHOLDER_END, TASK_PLACEHOLDER_START, inject_task_docs};
    use std::path::Path;

    fn inject(contents: &str) -> eyre::Result<String> {
        inject_task_docs(contents, "\n## `task`\n", Path::new("README.md"))
    }

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Re-add the TASK_PLACEHOLDER_END marker after the start marker, then rerun --inject
  2. Restore the complete marker pair from the generated (non-injected) output or git history
  3. Verify ordering: the end marker must appear strictly after the start marker in the file

Example fix

// before (docs/tasks.md)
<!-- TASK_PLACEHOLDER_START -->
| task | description |

// after
<!-- TASK_PLACEHOLDER_START -->
| task | description |
<!-- TASK_PLACEHOLDER_END -->
// then: mise generate task-docs --inject
Defensive patterns

Strategy: validation

Validate before calling

# ensure both markers, in order, before injecting
grep -n 'TASK_PLACEHOLDER_START\|TASK_PLACEHOLDER_END' docs/tasks.md
# start line must be < end line; if END is missing, re-add it:
# printf '<!-- TASK_PLACEHOLDER_END -->\n' >> docs/tasks.md

Prevention

When it happens

Trigger: Running task-docs injection on a file where someone deleted the end marker, a partial edit removed everything after the start marker, or the end marker appears before the start marker (so the post-start search misses it).

Common situations: Manual cleanup of a generated docs file that accidentally removed the closing marker; a truncated file from a failed merge; markers reordered when rearranging sections.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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