nikivdev/code · error

invalid js update target

Error message

invalid js update target

What it means

The JS-specific command planner destructures target.detail expecting UpdateTargetDetail::Js. If the target was classified with a different detail variant (or none), the let-else bails because JS manager commands cannot be built from a non-JS target.

Source

Thrown at src/deps.rs:266

        let root =
            find_js_workspace_root(&nearest_pkg, &ctx.search_root).unwrap_or(nearest_pkg.clone());
        let manager = opts.manager.unwrap_or_else(|| detect_manager(&root));
        let workspace = root != nearest_pkg || is_js_workspace_root(&root);

        Ok(Some(UpdateTarget {
            root,
            ecosystem: DepsEcosystem::Js,
            detail: UpdateTargetDetail::Js { manager, workspace },
        }))
    }

    fn build_commands(
        &self,
        target: &UpdateTarget,
        opts: &UpdateDepsOpts,
    ) -> Result<Vec<PlannedCommand>> {
        let UpdateTargetDetail::Js { manager, workspace } = target.detail else {
            bail!("invalid js update target");
        };

        let mut args = match manager {
            DepsManager::Pnpm => {
                let mut args = Vec::new();
                if workspace {
                    args.push("-r".to_string());
                }
                args.push("up".to_string());
                if opts.latest {
                    args.push("--latest".to_string());
                }
                args
            }
            DepsManager::Bun => {
                let mut args = vec!["update".to_string()];
                if opts.latest {
                    args.push("--latest".to_string());

View on GitHub (pinned to a747e741ae)

Solutions

  1. Fix target detection so package.json manifests produce UpdateTargetDetail::Js { manager, workspace }
  2. Ensure the target is routed to the planner matching its ecosystem, not unconditionally to the JS one
  3. When constructing UpdateTarget manually, always set detail = UpdateTargetDetail::Js with a valid DepsManager

Example fix

// before
let target = UpdateTarget { detail: UpdateTargetDetail::Generic };
planner.build_commands(&target, &opts)?  // bails

// after
let target = UpdateTarget { detail: UpdateTargetDetail::Js {
    manager: DepsManager::Npm, workspace: false,
}};
planner.build_commands(&target, &opts)?
Defensive patterns

Strategy: type-guard

Validate before calling

// verify detail variant before calling the JS planner
if !matches!(target.detail, UpdateTargetDetail::Js { .. }) {
    return Err(anyhow!("target is not a JS project"));
}

Type guard

fn is_js_target(t: &UpdateTarget) -> bool {
    matches!(t.detail, UpdateTargetDetail::Js { .. })
}

Prevention

When it happens

Trigger: build_commands on the JS planner receives an UpdateTarget whose detail is not UpdateTargetDetail::Js — i.e. target detection classified the manifest as another ecosystem (Rust/Go/Python) or left detail unset, then routed it to the JS planner.

Common situations: Mixed-repo detection bug where a package.json target got a generic detail; calling the planner API directly with a hand-constructed UpdateTarget; detection changes after a tool version bump.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/7fd552c139dfa442. Report an issue: GitHub.