jenkinsci/jenkins · error · IllegalStateException

'{view.getDisplayName()}' view can not be modified directly

Error message

'{view.getDisplayName()}' view can not be modified directly

What it means

IllegalStateException from remove-job-from-view when the target view is not a DirectlyModifiableView. Only view types implementing DirectlyModifiableView (e.g. ListView, AllView) support programmatic add/remove; aggregated/proxy views do not. The check happens after View.CONFIGURE permission already passed.

Source

Thrown at core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java:57

public class RemoveJobFromViewCommand extends CLICommand {

    @Argument(usage = "Name of the view", required = true, index = 0)
    private View view;

    @Argument(usage = "Job names", required = true, index = 1)
    private List<TopLevelItem> jobs;

    @Override
    public String getShortDescription() {
        return Messages.RemoveJobFromViewCommand_ShortDescription();
    }

    @Override
    protected int run() throws Exception {
        view.checkPermission(View.CONFIGURE);

        if (!(view instanceof DirectlyModifiableView))
            throw new IllegalStateException("'" + view.getDisplayName() + "' view can not be modified directly");

        for (TopLevelItem job : jobs) {
            ((DirectlyModifiableView) view).remove(job);
        }

        return 0;
    }
}

View on GitHub (pinned to 2e228ff40b)

Solutions

  1. Check `view instanceof DirectlyModifiableView` before calling remove.
  2. Target a ListView (or another DirectlyModifiableView) instead.
  3. Use the view's own configuration UI/API to remove the job.

Example fix

// before
((DirectlyModifiableView) view).remove(job);
// after
if (view instanceof DirectlyModifiableView) {
    ((DirectlyModifiableView) view).remove(job);
} else {
    throw new IllegalStateException("'" + view.getDisplayName() + "' is not directly modifiable");
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(view instanceof DirectlyModifiableView)) {
    throw new IllegalStateException("View '" + view.getDisplayName() + "' is not directly modifiable");
}

Type guard

boolean isModifiable(View v) { return v instanceof DirectlyModifiableView; }

Try / catch

try { ((DirectlyModifiableView) view).remove(job); }
catch (IllegalStateException e) { /* view type cannot be mutated directly */ }

Prevention

When it happens

Trigger: `remove-job-from-view` (or the equivalent API) against a view whose class does not implement DirectlyModifiableView (some plugin-provided dashboard/nested views).

Common situations: Pointing the command at a view type that only aggregates jobs but cannot be mutated directly; assuming all views behave like ListView.

Related errors


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/ed71fafc0c34b076. Report an issue: GitHub.