{"record":{"id":"9f739bc286b673d1","repo":"stanfordnlp/CoreNLP","slug":"cannot-nest-redwood-threaded-environments","errorCode":null,"errorMessage":"Cannot nest Redwood threaded environments","messagePattern":"Cannot nest Redwood threaded environments","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/util/logging/Redwood.java","lineNumber":429,"sourceCode":"\n  /**\n   * A utility method for closing calls to the anonymous startTrack() call.\n   */\n  public static void endTrack(){ endTrack(\"\"); }\n\n\n  /**\n   * Start a multithreaded logging environment. Log messages will be real time\n   * from one of the threads; as each thread finishes, another thread begins logging,\n   * first by making up the backlog, and then by printing any new log messages.\n   * A thread signals that it has finished logging with the finishThread() function;\n   * the multithreaded environment is ended with the endThreads() function.\n   *\n   * @param title The name of the thread group being started\n   */\n  public static void startThreads(String title){\n    if(isThreaded){\n      throw new IllegalStateException(\"Cannot nest Redwood threaded environments\");\n    }\n    startTrack(FORCE,\"Threads( \"+title+\" )\");\n    isThreaded = true;\n  }\n\n  /**\n   * Signal that this thread will not log any more messages in the multithreaded\n   * environment\n   */\n  public static void finishThread(){\n    //--Create Task\n    final long threadId = Thread.currentThread().getId();\n    Runnable finish = () -> releaseThreadControl(threadId);\n    //--Run Task\n    if(isThreaded){\n      //(case: multithreaded)\n      attemptThreadControl( threadId, finish );\n    } else {","sourceCodeStart":411,"sourceCodeEnd":447,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/util/logging/Redwood.java#L411-L447","documentation":"Redwood.startThreads(title) throws IllegalStateException if Redwood is already inside a threaded environment (isThreaded == true). Threaded environments used for concurrent logging cannot be nested; you must call endThreads() before starting another one.","triggerScenarios":"Calling Redwood.startThreads(...) twice without an intervening Redwood.endThreads(); calling startThreads from re-entrant/nested code (e.g. main starts threads and calls a method that also starts them).","commonSituations":"Two library subsystems each wrapping their work in Redwood threaded environments; recursive algorithms that call startThreads per level; forgotten endThreads on an early-return path.","solutions":["Call Redwood.endThreads() after the threaded section before any other startThreads()","Guard the call: only startThreads if !Redwood.isThreaded (or restructure so only the top level starts it)","Wrap the threaded section in try/finally so endThreads always runs","Move startThreads to the outermost caller (e.g. main) and remove inner ones"],"exampleFix":"// before\nRedwood.startThreads(\"workers\");\ndoWork();\nRedwood.startThreads(\"more\"); // throws\n// after\nRedwood.startThreads(\"workers\");\ntry { doWork(); } finally { Redwood.endThreads(); }\nRedwood.startThreads(\"more\");\ntry { moreWork(); } finally { Redwood.endThreads(); }","handlingStrategy":"validation","validationCode":"if (!Redwood.isThreaded) {\n  Redwood.startThreads(title);\n}","typeGuard":null,"tryCatchPattern":"try {\n  Redwood.startThreads(title);\n} catch (IllegalStateException e) {\n  // already threaded — reuse the existing threaded environment\n}","preventionTips":["Start threaded environments only at one top-level site","Always endThreads() in a finally block","Search codebase for duplicate startThreads calls before nesting library calls","Avoid startThreads inside recursive or re-entrant code"],"tags":["logging","redwood","nesting","threads"],"backgroundTag":"unsupported-nesting","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}