zeroclaw-labs/zeroclaw · error · anyhow::Error

Lark/Feishu marker target is empty

Error message

Lark/Feishu marker target is empty

What it means

validate_lark_marker_target is the first stop when turning an outgoing media marker (image/file kind like image, document, video, voice) into an uploadable local path; it rejects a target that trims to empty before any scheme or workspace checks. The marker target is supposed to be a workspace-relative (or absolute) file path, so an empty string means the agent/tool that produced the marker emitted no path at all.

Source

Thrown at crates/zeroclaw-channels/src/lark.rs:575

}

fn lark_outgoing_media_from_marker(
    kind: String,
    target: String,
) -> Option<LarkOutgoingMediaMarker> {
    Some(LarkOutgoingMediaMarker {
        kind: LarkOutgoingMediaKind::from_marker_kind(&kind)?,
        target,
    })
}

fn validate_lark_marker_target(
    target: &str,
    workspace_dir: Option<&Path>,
) -> anyhow::Result<PathBuf> {
    let trimmed = target.trim();
    if trimmed.is_empty() {
        anyhow::bail!("Lark/Feishu marker target is empty");
    }

    let lower = trimmed.to_ascii_lowercase();
    if lower.starts_with("http://")
        || lower.starts_with("https://")
        || lower.starts_with("data:")
        || lower.starts_with("file:")
        || lower.contains("://")
    {
        ::zeroclaw_log::record!(
            WARN,
            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)
                .with_attrs(::serde_json::json!({"reason": "disallowed_scheme"})),
            "lark: marker target uses disallowed scheme"
        );
        anyhow::bail!("Lark/Feishu marker target uses a disallowed scheme");
    }

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Fix the marker producer (agent tool or prompt) so the target is always the non-empty path of the generated file
  2. Validate marker payloads at the boundary where the model's structured output is parsed — drop or retry markers with a blank target before they reach the channel
  3. If a file-generation tool failed upstream, make its failure visible instead of letting an empty marker flow into send
Defensive patterns

Strategy: validation

Validate before calling

// Validate markers at parse time, before they reach the channel:
fn valid_marker(kind: &str, target: &str) -> bool {
    matches!(kind.to_ascii_lowercase().as_str(), "image"|"photo"|"document"|"file"|"video"|"audio"|"voice")
        && !target.trim().is_empty()
}

Try / catch

if let Err(e) = channel.send(&msg).await {
    if e.to_string().contains("marker target is empty") {
        // drop or regenerate the marker upstream; do not retry the same message
    }
}

Prevention

When it happens

Trigger: The model emits a media marker (e.g. an image attachment directive) whose target field is "" or only whitespace; resolve_lark_media_marker (called from send/finalize_draft) routes it into validate_lark_marker_target and the empty-trim guard fires.

Common situations: Agent prompt/template for Lark media output has an empty placeholder; a tool that generates files failed but still emitted a marker; JSON marker parsing lost the path field (key typo like 'path' vs 'target').

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/89dd40c418981282. Report an issue: GitHub.