MuntashirAkon/AppManager · error · java.io.IOException

ADB command did not produce

Error message

ADB command did not produce ${successPrefix}

What it means

executeAdbCommand sends an ADB shell command and waits for completion; a success marker identified by successPrefix is expected in the output. If the command finished but the marker never appeared, an IOException wrapping the captured read failure is thrown, meaning the ADB command ran but did not produce the expected result.

Solutions

  1. Inspect the wrapped failure cause (readFailure) for the real ADB error and fix that underlying issue
  2. Verify ADB is authorized and adbd is running on the device (adb devices, check authorization prompt)
  3. Retry the operation once; transient ADB daemon startup races often succeed on a second attempt
  4. Check device storage and SELinux denials in logcat that may abort the command

Example fix

// before
throw new IOException("ADB command did not produce " + successPrefix, failure);
// after
if (failure != null) {
    throw new IOException("ADB command did not produce " + successPrefix + ": " + failure.getMessage(), failure);
} else {
    throw new IOException("ADB command did not produce " + successPrefix);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (AdbUtils.isAdbdRunning()) { /* safe to run ADB commands */ }

Try / catch

try {
    executeAdbCommand(...);
} catch (SocketTimeoutException e) {
    // command hung: increase timeout or kill adb server
} catch (IOException e) {
    Throwable cause = e.getCause();
    Log.e(TAG, "ADB command failed: " + (cause != null ? cause.getMessage() : "no success marker"), e);
}

Prevention

When it happens

Trigger: Calling useAdbStartServer or stopServer when the underlying ADB command exits without the expected success marker in its output stream, e.g. adb server start fails, adbd rejects the command, or remote output ends early.

Common situations: ADB not authorized on the device, adbd running on an unexpected port, device storage full preventing the server from starting, or SELinux policies blocking the shell command.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/128702d2f887a01a. Report an issue: GitHub.

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/servermanager/LocalServerManager.java:327

                    }
                }
            } catch (Throwable e) {
                readFailure.set(e);
            } finally {
                commandWatcher.countDown();
            }
        }, "am-adb-command-output");
        outputThread.start();
        try {
            outputStream.write("id\n".getBytes(StandardCharsets.UTF_8));
            outputStream.write((command + "\n").getBytes(StandardCharsets.UTF_8));
            outputStream.flush();
            if (!commandWatcher.await(timeout, timeoutUnit)) {
                throw new SocketTimeoutException("Timed out waiting for ADB command: " + command);
            }
            if (!commandSucceeded.get()) {
                Throwable failure = readFailure.get();
                throw new IOException("ADB command did not produce " + successPrefix, failure);
            }
        } finally {
            outputThread.interrupt();
        }
    }

    @WorkerThread
    private void useRootStartServer() throws Exception {
        if (!Ops.hasRoot()) {
            throw new Exception("Root access denied");
        }
        String command = ServerConfig.getServerRunnerCommand();
        // + "\n" + "supolicy --live 'allow qti_init_shell zygote_exec file execute'";
        Log.d(TAG, "useRootStartServer: %s", command);
        Runner.Result result = Runner.runCommand(command);

        Log.d(TAG, "useRootStartServer: %s", result.getOutput());
        if (!result.isSuccessful()) {

View on GitHub (pinned to 0152f468fc)