{"record":{"id":"3f3d80a825ea5ec1","repo":"wavetermdev/waveterm","slug":"unknown-controller-type-q-3f3d80","errorCode":null,"errorMessage":"unknown controller type %q","messagePattern":"unknown controller type %q","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/blockcontroller/shellcontroller.go","lineNumber":421,"sourceCode":"\t\tcmdOpts.Interactive = true\n\t\tcmdOpts.Login = true\n\t\tcmdOpts.Cwd = blockMeta.GetString(waveobj.MetaKey_CmdCwd, \"\")\n\t\tif cmdOpts.Cwd != \"\" {\n\t\t\tcwdPath, err := wavebase.ExpandHomeDir(cmdOpts.Cwd)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcmdOpts.Cwd = cwdPath\n\t\t}\n\t} else if bc.ControllerType == BlockController_Cmd {\n\t\tvar cmdOptsPtr *shellexec.CommandOptsType\n\t\tcmdStr, cmdOptsPtr, err = createCmdStrAndOpts(bc.BlockId, blockMeta, remoteName)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcmdOpts = *cmdOptsPtr\n\t} else {\n\t\treturn nil, fmt.Errorf(\"unknown controller type %q\", bc.ControllerType)\n\t}\n\tvar shellProc *shellexec.ShellProc\n\tswapToken := makeSwapToken(ctx, logCtx, bc.BlockId, blockMeta, remoteName, connUnion.ShellType)\n\tcmdOpts.SwapToken = swapToken\n\tblocklogger.Debugf(logCtx, \"[conndebug] created swaptoken: %s\\n\", swapToken.Token)\n\tif connUnion.ConnType == ConnType_Wsl {\n\t\twslConn := connUnion.WslConn\n\t\tif !connUnion.WshEnabled {\n\t\t\tshellProc, err = shellexec.StartWslShellProcNoWsh(ctx, rc.TermSize, cmdStr, cmdOpts, wslConn)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {\n\t\t\tsockName := wslConn.GetDomainSocketName()\n\t\t\trpcContext := wshrpc.RpcContext{\n\t\t\t\tProcRoute: true,\n\t\t\t\tSockName:  sockName,\n\t\t\t\tBlockId:   bc.BlockId,","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/blockcontroller/shellcontroller.go#L403-L439","documentation":"Returned when ShellController.ControllerType is neither the controller type handled by createCmdStrAndOpts nor any known branch in setupAndStartShellProcess. It is an internal invariant violation: the block's controller was created with an unrecognized type value.","triggerScenarios":"DoRunShellCommand invoked on a ShellController whose bc.ControllerType holds an unexpected/legacy/empty value so the if/else chain falls through to the final else.","commonSituations":"Session data restored from an older Wave version with a deprecated controller type; corrupted block metadata in the workspace state; a plugin or experimental build writing a custom ControllerType.","solutions":["Delete and re-create the terminal block so a fresh ShellController is built with a valid ControllerType","Upgrade/downgrade so app version matches the workspace/session data version","Inspect the saved block state and correct ControllerType to a supported value","Report as a bug if a stock terminal block reproduces this — it indicates state corruption"],"exampleFix":"// before: stale restored block with unknown ControllerType reused as-is\nshellProc, err := bc.setupAndStartShellProcess(logCtx, rc, blockMeta)\n\n// after: recreate the block controller if type is unknown\nif !isKnownControllerType(bc.ControllerType) {\n    controller = controllerRegistry.Recreate(bc.BlockId)\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func knownControllerType(t ControllerType) bool {\n    switch t {\n    case ControllerType_Shell:\n        return true\n    default:\n        return false\n    }\n}\n// guard: if !knownControllerType(bc.ControllerType) { recreate block controller }","tryCatchPattern":"proc, err := bc.setupAndStartShellProcess(logCtx, rc, blockMeta)\nif err != nil && strings.Contains(err.Error(), \"unknown controller type\") {\n    // recreate the block/controller and retry once\n}","preventionTips":["Migrate legacy ControllerType values when loading saved state from older versions","Re-create suspect blocks instead of reusing restored controller objects","Keep app and workspace state versions aligned"],"tags":["internal","state-corruption","versioning"],"backgroundTag":"unknown-controller-type","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}