Skip to content

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create - #6

Merged
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error
Jul 29, 2026
Merged

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create#6
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error

Conversation

@enisze

Copy link
Copy Markdown
Owner

Problem

Sending the first message on a local draft thread embeds a bootstrap.createThread in the thread.turn.start command, using a threadId the client pre-generated. The server expands that into a real thread.create. If that threadId already exists server-side (a double-send, a retry, or a draft that was already promoted), the requireThreadAbsent invariant fires, the whole bootstrap turn fails, and the user sees an error banner:

Orchestration command invariant failed (thread.create): Thread '…' already exists and cannot be created twice.

Fix

Bootstrapping a draft is inherently a create-if-absent operation, so the duplicate thread.create should be a no-op rather than a hard failure. The bootstrap path now catches that specific invariant, treats it as a no-op, and continues the turn against the existing thread. The message lands, the thread starts, and the draft route's existing navigation logic moves the user into the already-created chat — instead of showing the error.

Done server-side because the error only reaches the client as a generic OrchestrationDispatchCommandError message string; detecting it in the UI would mean fragile string matching and would drop the user's message.

Changes

  • commandInvariants.ts — extracted the "already exists" detail into a shared function and added isThreadAlreadyExistsInvariantError(error, threadId), a precise predicate (matches on both commandType === "thread.create" and the exact detail, so it never swallows a different invariant like a missing project).
  • ws.ts — the bootstrap thread.create dispatch catches OrchestrationCommandInvariantError, treats the "already exists" case as a no-op, and keeps createdThread = false so failure-cleanup never deletes a pre-existing thread.
  • commandInvariants.test.ts — coverage for the new predicate, including negative cases.

Verification

  • pnpm typecheck — clean
  • Orchestration suite: 191/191 passing, including the new predicate test

🤖 Generated with Claude Code

…trap thread.create
Bootstrapping a draft is a create-if-absent operation: the client generates
the threadId before the thread exists, so a duplicate send, a retry, or an
already-promoted draft can target a threadId the server already has. Previously
that hard-failed the whole turn with an "already exists and cannot be created
twice" invariant, surfacing an error banner.
Treat that specific invariant as a no-op in the bootstrap path and continue the
turn against the existing thread. The message lands, the thread starts, and the
draft route navigates the user into the already-created chat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@enisze
enisze merged commit 979e8e6 into mainJul 29, 2026
@enisze
enisze deleted the t3code/open-existing-thread-on-create-error branch July 29, 2026 22:33
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@enisze
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(server): open existing chat instead of failing on duplicate bootstrap thread.create by enisze · Pull Request #6 · enisze/t3code · GitHub
Skip to content

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create - #6

Merged
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error
Jul 29, 2026
Merged

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create#6
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error

Conversation

@enisze

Copy link
Copy Markdown
Owner

Problem

Sending the first message on a local draft thread embeds a bootstrap.createThread in the thread.turn.start command, using a threadId the client pre-generated. The server expands that into a real thread.create. If that threadId already exists server-side (a double-send, a retry, or a draft that was already promoted), the requireThreadAbsent invariant fires, the whole bootstrap turn fails, and the user sees an error banner:

Orchestration command invariant failed (thread.create): Thread '…' already exists and cannot be created twice.

Fix

Bootstrapping a draft is inherently a create-if-absent operation, so the duplicate thread.create should be a no-op rather than a hard failure. The bootstrap path now catches that specific invariant, treats it as a no-op, and continues the turn against the existing thread. The message lands, the thread starts, and the draft route's existing navigation logic moves the user into the already-created chat — instead of showing the error.

Done server-side because the error only reaches the client as a generic OrchestrationDispatchCommandError message string; detecting it in the UI would mean fragile string matching and would drop the user's message.

Changes

  • commandInvariants.ts — extracted the "already exists" detail into a shared function and added isThreadAlreadyExistsInvariantError(error, threadId), a precise predicate (matches on both commandType === "thread.create" and the exact detail, so it never swallows a different invariant like a missing project).
  • ws.ts — the bootstrap thread.create dispatch catches OrchestrationCommandInvariantError, treats the "already exists" case as a no-op, and keeps createdThread = false so failure-cleanup never deletes a pre-existing thread.
  • commandInvariants.test.ts — coverage for the new predicate, including negative cases.

Verification

  • pnpm typecheck — clean
  • Orchestration suite: 191/191 passing, including the new predicate test

🤖 Generated with Claude Code

…trap thread.create
Bootstrapping a draft is a create-if-absent operation: the client generates
the threadId before the thread exists, so a duplicate send, a retry, or an
already-promoted draft can target a threadId the server already has. Previously
that hard-failed the whole turn with an "already exists and cannot be created
twice" invariant, surfacing an error banner.
Treat that specific invariant as a no-op in the bootstrap path and continue the
turn against the existing thread. The message lands, the thread starts, and the
draft route navigates the user into the already-created chat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@enisze
enisze merged commit 979e8e6 into mainJul 29, 2026
@enisze
enisze deleted the t3code/open-existing-thread-on-create-error branch July 29, 2026 22:33
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@enisze
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(server): open existing chat instead of failing on duplicate bootstrap thread.create by enisze · Pull Request #6 · enisze/t3code · GitHub
Skip to content

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create - #6

Merged
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error
Jul 29, 2026
Merged

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create#6
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error

Conversation

@enisze

Copy link
Copy Markdown
Owner

Problem

Sending the first message on a local draft thread embeds a bootstrap.createThread in the thread.turn.start command, using a threadId the client pre-generated. The server expands that into a real thread.create. If that threadId already exists server-side (a double-send, a retry, or a draft that was already promoted), the requireThreadAbsent invariant fires, the whole bootstrap turn fails, and the user sees an error banner:

Orchestration command invariant failed (thread.create): Thread '…' already exists and cannot be created twice.

Fix

Bootstrapping a draft is inherently a create-if-absent operation, so the duplicate thread.create should be a no-op rather than a hard failure. The bootstrap path now catches that specific invariant, treats it as a no-op, and continues the turn against the existing thread. The message lands, the thread starts, and the draft route's existing navigation logic moves the user into the already-created chat — instead of showing the error.

Done server-side because the error only reaches the client as a generic OrchestrationDispatchCommandError message string; detecting it in the UI would mean fragile string matching and would drop the user's message.

Changes

  • commandInvariants.ts — extracted the "already exists" detail into a shared function and added isThreadAlreadyExistsInvariantError(error, threadId), a precise predicate (matches on both commandType === "thread.create" and the exact detail, so it never swallows a different invariant like a missing project).
  • ws.ts — the bootstrap thread.create dispatch catches OrchestrationCommandInvariantError, treats the "already exists" case as a no-op, and keeps createdThread = false so failure-cleanup never deletes a pre-existing thread.
  • commandInvariants.test.ts — coverage for the new predicate, including negative cases.

Verification

  • pnpm typecheck — clean
  • Orchestration suite: 191/191 passing, including the new predicate test

🤖 Generated with Claude Code

…trap thread.create
Bootstrapping a draft is a create-if-absent operation: the client generates
the threadId before the thread exists, so a duplicate send, a retry, or an
already-promoted draft can target a threadId the server already has. Previously
that hard-failed the whole turn with an "already exists and cannot be created
twice" invariant, surfacing an error banner.
Treat that specific invariant as a no-op in the bootstrap path and continue the
turn against the existing thread. The message lands, the thread starts, and the
draft route navigates the user into the already-created chat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@enisze
enisze merged commit 979e8e6 into mainJul 29, 2026
@enisze
enisze deleted the t3code/open-existing-thread-on-create-error branch July 29, 2026 22:33
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@enisze
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(server): open existing chat instead of failing on duplicate bootstrap thread.create by enisze · Pull Request #6 · enisze/t3code · GitHub
Skip to content

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create - #6

Merged
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error
Jul 29, 2026
Merged

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create#6
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error

Conversation

@enisze

Copy link
Copy Markdown
Owner

Problem

Sending the first message on a local draft thread embeds a bootstrap.createThread in the thread.turn.start command, using a threadId the client pre-generated. The server expands that into a real thread.create. If that threadId already exists server-side (a double-send, a retry, or a draft that was already promoted), the requireThreadAbsent invariant fires, the whole bootstrap turn fails, and the user sees an error banner:

Orchestration command invariant failed (thread.create): Thread '…' already exists and cannot be created twice.

Fix

Bootstrapping a draft is inherently a create-if-absent operation, so the duplicate thread.create should be a no-op rather than a hard failure. The bootstrap path now catches that specific invariant, treats it as a no-op, and continues the turn against the existing thread. The message lands, the thread starts, and the draft route's existing navigation logic moves the user into the already-created chat — instead of showing the error.

Done server-side because the error only reaches the client as a generic OrchestrationDispatchCommandError message string; detecting it in the UI would mean fragile string matching and would drop the user's message.

Changes

  • commandInvariants.ts — extracted the "already exists" detail into a shared function and added isThreadAlreadyExistsInvariantError(error, threadId), a precise predicate (matches on both commandType === "thread.create" and the exact detail, so it never swallows a different invariant like a missing project).
  • ws.ts — the bootstrap thread.create dispatch catches OrchestrationCommandInvariantError, treats the "already exists" case as a no-op, and keeps createdThread = false so failure-cleanup never deletes a pre-existing thread.
  • commandInvariants.test.ts — coverage for the new predicate, including negative cases.

Verification

  • pnpm typecheck — clean
  • Orchestration suite: 191/191 passing, including the new predicate test

🤖 Generated with Claude Code

…trap thread.create
Bootstrapping a draft is a create-if-absent operation: the client generates
the threadId before the thread exists, so a duplicate send, a retry, or an
already-promoted draft can target a threadId the server already has. Previously
that hard-failed the whole turn with an "already exists and cannot be created
twice" invariant, surfacing an error banner.
Treat that specific invariant as a no-op in the bootstrap path and continue the
turn against the existing thread. The message lands, the thread starts, and the
draft route navigates the user into the already-created chat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@enisze
enisze merged commit 979e8e6 into mainJul 29, 2026
@enisze
enisze deleted the t3code/open-existing-thread-on-create-error branch July 29, 2026 22:33
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@enisze
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(server): open existing chat instead of failing on duplicate bootstrap thread.create by enisze · Pull Request #6 · enisze/t3code · GitHub
Skip to content

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create - #6

Merged
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error
Jul 29, 2026
Merged

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create#6
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error

Conversation

@enisze

Copy link
Copy Markdown
Owner

Problem

Sending the first message on a local draft thread embeds a bootstrap.createThread in the thread.turn.start command, using a threadId the client pre-generated. The server expands that into a real thread.create. If that threadId already exists server-side (a double-send, a retry, or a draft that was already promoted), the requireThreadAbsent invariant fires, the whole bootstrap turn fails, and the user sees an error banner:

Orchestration command invariant failed (thread.create): Thread '…' already exists and cannot be created twice.

Fix

Bootstrapping a draft is inherently a create-if-absent operation, so the duplicate thread.create should be a no-op rather than a hard failure. The bootstrap path now catches that specific invariant, treats it as a no-op, and continues the turn against the existing thread. The message lands, the thread starts, and the draft route's existing navigation logic moves the user into the already-created chat — instead of showing the error.

Done server-side because the error only reaches the client as a generic OrchestrationDispatchCommandError message string; detecting it in the UI would mean fragile string matching and would drop the user's message.

Changes

  • commandInvariants.ts — extracted the "already exists" detail into a shared function and added isThreadAlreadyExistsInvariantError(error, threadId), a precise predicate (matches on both commandType === "thread.create" and the exact detail, so it never swallows a different invariant like a missing project).
  • ws.ts — the bootstrap thread.create dispatch catches OrchestrationCommandInvariantError, treats the "already exists" case as a no-op, and keeps createdThread = false so failure-cleanup never deletes a pre-existing thread.
  • commandInvariants.test.ts — coverage for the new predicate, including negative cases.

Verification

  • pnpm typecheck — clean
  • Orchestration suite: 191/191 passing, including the new predicate test

🤖 Generated with Claude Code

…trap thread.create
Bootstrapping a draft is a create-if-absent operation: the client generates
the threadId before the thread exists, so a duplicate send, a retry, or an
already-promoted draft can target a threadId the server already has. Previously
that hard-failed the whole turn with an "already exists and cannot be created
twice" invariant, surfacing an error banner.
Treat that specific invariant as a no-op in the bootstrap path and continue the
turn against the existing thread. The message lands, the thread starts, and the
draft route navigates the user into the already-created chat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@enisze
enisze merged commit 979e8e6 into mainJul 29, 2026
@enisze
enisze deleted the t3code/open-existing-thread-on-create-error branch July 29, 2026 22:33
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@enisze
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(server): open existing chat instead of failing on duplicate bootstrap thread.create by enisze · Pull Request #6 · enisze/t3code · GitHub
Skip to content

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create - #6

Merged
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error
Jul 29, 2026
Merged

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create#6
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error

Conversation

@enisze

Copy link
Copy Markdown
Owner

Problem

Sending the first message on a local draft thread embeds a bootstrap.createThread in the thread.turn.start command, using a threadId the client pre-generated. The server expands that into a real thread.create. If that threadId already exists server-side (a double-send, a retry, or a draft that was already promoted), the requireThreadAbsent invariant fires, the whole bootstrap turn fails, and the user sees an error banner:

Orchestration command invariant failed (thread.create): Thread '…' already exists and cannot be created twice.

Fix

Bootstrapping a draft is inherently a create-if-absent operation, so the duplicate thread.create should be a no-op rather than a hard failure. The bootstrap path now catches that specific invariant, treats it as a no-op, and continues the turn against the existing thread. The message lands, the thread starts, and the draft route's existing navigation logic moves the user into the already-created chat — instead of showing the error.

Done server-side because the error only reaches the client as a generic OrchestrationDispatchCommandError message string; detecting it in the UI would mean fragile string matching and would drop the user's message.

Changes

  • commandInvariants.ts — extracted the "already exists" detail into a shared function and added isThreadAlreadyExistsInvariantError(error, threadId), a precise predicate (matches on both commandType === "thread.create" and the exact detail, so it never swallows a different invariant like a missing project).
  • ws.ts — the bootstrap thread.create dispatch catches OrchestrationCommandInvariantError, treats the "already exists" case as a no-op, and keeps createdThread = false so failure-cleanup never deletes a pre-existing thread.
  • commandInvariants.test.ts — coverage for the new predicate, including negative cases.

Verification

  • pnpm typecheck — clean
  • Orchestration suite: 191/191 passing, including the new predicate test

🤖 Generated with Claude Code

…trap thread.create
Bootstrapping a draft is a create-if-absent operation: the client generates
the threadId before the thread exists, so a duplicate send, a retry, or an
already-promoted draft can target a threadId the server already has. Previously
that hard-failed the whole turn with an "already exists and cannot be created
twice" invariant, surfacing an error banner.
Treat that specific invariant as a no-op in the bootstrap path and continue the
turn against the existing thread. The message lands, the thread starts, and the
draft route navigates the user into the already-created chat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@enisze
enisze merged commit 979e8e6 into mainJul 29, 2026
@enisze
enisze deleted the t3code/open-existing-thread-on-create-error branch July 29, 2026 22:33
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@enisze
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(server): open existing chat instead of failing on duplicate bootstrap thread.create by enisze · Pull Request #6 · enisze/t3code · GitHub
Skip to content

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create - #6

Merged
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error
Jul 29, 2026
Merged

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create#6
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error

Conversation

@enisze

Copy link
Copy Markdown
Owner

Problem

Sending the first message on a local draft thread embeds a bootstrap.createThread in the thread.turn.start command, using a threadId the client pre-generated. The server expands that into a real thread.create. If that threadId already exists server-side (a double-send, a retry, or a draft that was already promoted), the requireThreadAbsent invariant fires, the whole bootstrap turn fails, and the user sees an error banner:

Orchestration command invariant failed (thread.create): Thread '…' already exists and cannot be created twice.

Fix

Bootstrapping a draft is inherently a create-if-absent operation, so the duplicate thread.create should be a no-op rather than a hard failure. The bootstrap path now catches that specific invariant, treats it as a no-op, and continues the turn against the existing thread. The message lands, the thread starts, and the draft route's existing navigation logic moves the user into the already-created chat — instead of showing the error.

Done server-side because the error only reaches the client as a generic OrchestrationDispatchCommandError message string; detecting it in the UI would mean fragile string matching and would drop the user's message.

Changes

  • commandInvariants.ts — extracted the "already exists" detail into a shared function and added isThreadAlreadyExistsInvariantError(error, threadId), a precise predicate (matches on both commandType === "thread.create" and the exact detail, so it never swallows a different invariant like a missing project).
  • ws.ts — the bootstrap thread.create dispatch catches OrchestrationCommandInvariantError, treats the "already exists" case as a no-op, and keeps createdThread = false so failure-cleanup never deletes a pre-existing thread.
  • commandInvariants.test.ts — coverage for the new predicate, including negative cases.

Verification

  • pnpm typecheck — clean
  • Orchestration suite: 191/191 passing, including the new predicate test

🤖 Generated with Claude Code

…trap thread.create
Bootstrapping a draft is a create-if-absent operation: the client generates
the threadId before the thread exists, so a duplicate send, a retry, or an
already-promoted draft can target a threadId the server already has. Previously
that hard-failed the whole turn with an "already exists and cannot be created
twice" invariant, surfacing an error banner.
Treat that specific invariant as a no-op in the bootstrap path and continue the
turn against the existing thread. The message lands, the thread starts, and the
draft route navigates the user into the already-created chat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@enisze
enisze merged commit 979e8e6 into mainJul 29, 2026
@enisze
enisze deleted the t3code/open-existing-thread-on-create-error branch July 29, 2026 22:33
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@enisze
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); fix(server): open existing chat instead of failing on duplicate bootstrap thread.create by enisze · Pull Request #6 · enisze/t3code · GitHub
Skip to content

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create - #6

Merged
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error
Jul 29, 2026
Merged

fix(server): open existing chat instead of failing on duplicate bootstrap thread.create#6
enisze merged 1 commit into
mainfrom
t3code/open-existing-thread-on-create-error

Conversation

@enisze

Copy link
Copy Markdown
Owner

Problem

Sending the first message on a local draft thread embeds a bootstrap.createThread in the thread.turn.start command, using a threadId the client pre-generated. The server expands that into a real thread.create. If that threadId already exists server-side (a double-send, a retry, or a draft that was already promoted), the requireThreadAbsent invariant fires, the whole bootstrap turn fails, and the user sees an error banner:

Orchestration command invariant failed (thread.create): Thread '…' already exists and cannot be created twice.

Fix

Bootstrapping a draft is inherently a create-if-absent operation, so the duplicate thread.create should be a no-op rather than a hard failure. The bootstrap path now catches that specific invariant, treats it as a no-op, and continues the turn against the existing thread. The message lands, the thread starts, and the draft route's existing navigation logic moves the user into the already-created chat — instead of showing the error.

Done server-side because the error only reaches the client as a generic OrchestrationDispatchCommandError message string; detecting it in the UI would mean fragile string matching and would drop the user's message.

Changes

  • commandInvariants.ts — extracted the "already exists" detail into a shared function and added isThreadAlreadyExistsInvariantError(error, threadId), a precise predicate (matches on both commandType === "thread.create" and the exact detail, so it never swallows a different invariant like a missing project).
  • ws.ts — the bootstrap thread.create dispatch catches OrchestrationCommandInvariantError, treats the "already exists" case as a no-op, and keeps createdThread = false so failure-cleanup never deletes a pre-existing thread.
  • commandInvariants.test.ts — coverage for the new predicate, including negative cases.

Verification

  • pnpm typecheck — clean
  • Orchestration suite: 191/191 passing, including the new predicate test

🤖 Generated with Claude Code

…trap thread.create
Bootstrapping a draft is a create-if-absent operation: the client generates
the threadId before the thread exists, so a duplicate send, a retry, or an
already-promoted draft can target a threadId the server already has. Previously
that hard-failed the whole turn with an "already exists and cannot be created
twice" invariant, surfacing an error banner.
Treat that specific invariant as a no-op in the bootstrap path and continue the
turn against the existing thread. The message lands, the thread starts, and the
draft route navigates the user into the already-created chat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@enisze
enisze merged commit 979e8e6 into mainJul 29, 2026
@enisze
enisze deleted the t3code/open-existing-thread-on-create-error branch July 29, 2026 22:33
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@enisze