{"record":{"id":"ed71fafc0c34b076","repo":"jenkinsci/jenkins","slug":"view-getdisplayname-view-can-not-be-modified","errorCode":null,"errorMessage":"'{view.getDisplayName()}' view can not be modified directly","messagePattern":"'(.+?)' view can not be modified directly","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java","lineNumber":57,"sourceCode":"public class RemoveJobFromViewCommand extends CLICommand {\n\n    @Argument(usage = \"Name of the view\", required = true, index = 0)\n    private View view;\n\n    @Argument(usage = \"Job names\", required = true, index = 1)\n    private List<TopLevelItem> jobs;\n\n    @Override\n    public String getShortDescription() {\n        return Messages.RemoveJobFromViewCommand_ShortDescription();\n    }\n\n    @Override\n    protected int run() throws Exception {\n        view.checkPermission(View.CONFIGURE);\n\n        if (!(view instanceof DirectlyModifiableView))\n            throw new IllegalStateException(\"'\" + view.getDisplayName() + \"' view can not be modified directly\");\n\n        for (TopLevelItem job : jobs) {\n            ((DirectlyModifiableView) view).remove(job);\n        }\n\n        return 0;\n    }\n}\n","sourceCodeStart":39,"sourceCodeEnd":66,"githubUrl":"https://github.com/jenkinsci/jenkins/blob/2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc/core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java#L39-L66","documentation":"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.","triggerScenarios":"`remove-job-from-view` (or the equivalent API) against a view whose class does not implement DirectlyModifiableView (some plugin-provided dashboard/nested views).","commonSituations":"Pointing the command at a view type that only aggregates jobs but cannot be mutated directly; assuming all views behave like ListView.","solutions":["Check `view instanceof DirectlyModifiableView` before calling remove.","Target a ListView (or another DirectlyModifiableView) instead.","Use the view's own configuration UI/API to remove the job."],"exampleFix":"// before\n((DirectlyModifiableView) view).remove(job);\n// after\nif (view instanceof DirectlyModifiableView) {\n    ((DirectlyModifiableView) view).remove(job);\n} else {\n    throw new IllegalStateException(\"'\" + view.getDisplayName() + \"' is not directly modifiable\");\n}","handlingStrategy":"type-guard","validationCode":"if (!(view instanceof DirectlyModifiableView)) {\n    throw new IllegalStateException(\"View '\" + view.getDisplayName() + \"' is not directly modifiable\");\n}","typeGuard":"boolean isModifiable(View v) { return v instanceof DirectlyModifiableView; }","tryCatchPattern":"try { ((DirectlyModifiableView) view).remove(job); }\ncatch (IllegalStateException e) { /* view type cannot be mutated directly */ }","preventionTips":["InstanceOf-check DirectlyModifiableView before add/remove.","Prefer ListView when programmatic mutation is needed."],"tags":["cli","view","configuration","type-mismatch"],"backgroundTag":null,"analyzedSha":"2e228ff40b14dbc8b14ffbc6edf0e4383cf744fc","analyzedAt":"2026-08-14T07:07:15.274Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}