{"record":{"id":"29f3338f5d2a5183","repo":"MuntashirAkon/AppManager","slug":"token-is-not-found","errorCode":null,"errorMessage":"Token is not found.","messagePattern":"Token is not found\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/io/github/muntashirakon/AppManager/server/ServerHandler.java","lineNumber":53,"sourceCode":"    private final Server mServer;\n    private final boolean mRunInBackground;\n\n    private Handler mHandler;\n    private volatile boolean mIsDead = false;\n\n    ServerHandler(@NonNull LifecycleAgent lifecycleAgent) throws IOException {\n        mLifecycleAgent = lifecycleAgent;\n        mConfigParams = mLifecycleAgent.getConfigParams();\n        // Set params\n        System.out.println(\"Config params: \" + mConfigParams);\n        int port;\n        try {\n            port = Integer.parseInt(mConfigParams.getPath());\n        } catch (Exception e) {\n            throw new IOException(e);\n        }\n        String token = mConfigParams.getToken();\n        if (token == null) throw new IOException(\"Token is not found.\");\n        mRunInBackground = mConfigParams.isRunInBackground();\n        mServer = new Server(port, token, mLifecycleAgent, this);\n        mServer.mRunInBackground = mRunInBackground;\n        // If run in background not requested, stop server on timeout\n        if (!mRunInBackground) {\n            HandlerThread handlerThread = new HandlerThread(\"am_server_watcher\");\n            handlerThread.start();\n            mHandler = new Handler(handlerThread.getLooper()) {\n                @Override\n                public void handleMessage(@NonNull Message message) {\n                    super.handleMessage(message);\n                    if (message.what == MSG_TIMEOUT) {\n                        close();\n                    }\n                }\n            };\n            mHandler.sendEmptyMessageDelayed(MSG_TIMEOUT, DEFAULT_TIMEOUT);\n        }","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/server/src/main/java/io/github/muntashirakon/AppManager/server/ServerHandler.java#L35-L71","documentation":"ServerHandler builds its runtime configuration from mConfigParams: it parses the listen port from the config path and then requires the authentication token. If mConfigParams.getToken() returns null it throws IOException('Token is not found.') because the Server cannot authenticate any client without a shared token. This is a missing-required-configuration guard at server startup.","triggerScenarios":"Launching the AM server (am_server) without supplying the token as a config parameter — i.e. the invocation omits the token argument/component, the config Uri carries no token extra/query, or the caller constructing ServerHandler passed a params object with null token.","commonSituations":"Manually running the server binary on the command line and forgetting the token argument; stale launcher script from an older AppManager version with different argument layout; programmatic integration constructing ServerHandler config without setting the token; shell expansion dropping an argument.","solutions":["Pass the token when starting the server: use AppManager's own launch path (which generates and embeds the token) rather than a hand-written command.","If launching manually, inspect how mConfigParams is parsed (path = port, token param) and supply both correctly in the expected format.","Regenerate/re-run the server starter from the current AppManager build so the argument layout matches this code version.","Add a startup check in your launcher script that aborts with a clear message when the token argument is empty."],"exampleFix":"// before: manual launch missing token\nam_server 7899\n// after: supply token in the expected config format (via AppManager's generated invocation)\nam_server <config-with-port-and-token>\n// or in code:\nconfig.setToken(token); // ensure non-null before new ServerHandler(config)\n","handlingStrategy":"validation","validationCode":"String token = mConfigParams.getToken();\nif (token == null || token.isEmpty()) {\n    throw new IllegalArgumentException(\"Server launch requires a token; regenerate via AppManager's server starter.\");\n}\nint port = Integer.parseInt(mConfigParams.getPath()); // also guard NumberFormatException\n","typeGuard":null,"tryCatchPattern":"try {\n    new ServerHandler(configParams).start();\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Token is not found\")) {\n        // regenerate config with a fresh token and relaunch\n    }\n}\n","preventionTips":["Always start the server via AppManager's generated invocation, never a hand-rolled command line.","Validate config (port parses, token non-null) before constructing ServerHandler.","Keep launcher scripts in sync with the AppManager version's expected argument layout.","Fail fast in wrappers: abort launch scripts when the token argument is empty."],"tags":["missing-token","server-startup","configuration"],"backgroundTag":"missing-required-config-field","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}