Skip to content

Conversation

@jog1t
Copy link
Contributor

@jog1t jog1t commented Oct 20, 2025

No description provided.

@vercel
Copy link

vercel bot commented Oct 20, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
rivet-inspector Error Error Oct 24, 2025 10:12pm
2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
rivet-cloud Ignored Ignored Oct 24, 2025 10:12pm
rivet-site Ignored Ignored Preview Oct 24, 2025 10:12pm

Copy link
Contributor Author

jog1t commented Oct 20, 2025

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add the label merge-queue to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 20, 2025

Open in StackBlitz

npm i https://pkg.pr.new/rivet-dev/engine/@rivetkit/engine-runner@3229
npm i https://pkg.pr.new/rivet-dev/engine/@rivetkit/engine-runner-protocol@3229

commit: ce7ecee

@claude
Copy link

claude bot commented Oct 20, 2025

PR Review: Fix Inspector Working Again

Overview

This PR fixes the actor inspector functionality by properly handling authentication tokens and improving the REPL worker implementation. The changes span across the frontend data providers, actor worker logic, and dependency management.

Code Quality & Best Practices ✅

Strengths:

  • Good use of TypeScript patterns with ts-pattern for type-safe matching
  • Proper async/await handling throughout
  • Clean separation of concerns between worker and container logic
  • Good use of structuredClone for deep cloning init data (actor-repl.worker.ts:117)
  • Proper error handling with try-catch blocks

Minor Improvements:

  1. actor-worker-context.tsx:42 - Type assertion as string could be improved with proper type narrowing:

    return (data?.metadata?.inspectorToken as string) || "";
    // Consider: return typeof data?.metadata?.inspectorToken === 'string' ? data.metadata.inspectorToken : '';
  2. actor-editable-state.tsx:87 - Good use of mutateAsync instead of mutate for proper awaiting, though you could add error handling:

    onClick={async () => {
      try {
        await mutateAsync(JSON.parse(value || ""));
        setIsEditing(false);
        setValue(null);
      } catch (error) {
        // Consider showing error feedback to user
      }
    }}

Potential Bugs & Issues ⚠️

  1. Token Function Resolution (actor-worker-container.ts:144-147)

    • The code properly handles function tokens by awaiting them, but there's no error handling if the token function throws:
    engineToken:
      typeof this.#meta?.engineToken === "function"
        ? await this.#meta?.engineToken()
        : this.#meta?.engineToken,
    • Recommendation: Wrap in try-catch to handle token retrieval failures gracefully.
  2. Empty Runner Name (actor-worker-context.tsx:68)

    • useInspectorToken(runner || "") passes an empty string when runner is undefined/null
    • This could lead to unnecessary query execution with invalid parameters
    • Recommendation: Consider early return or conditional execution when runner is falsy.
  3. Error Response Handling (actor-repl.worker.ts:210-216)

    • The error handling tries JSON first, then falls back to text, which is good
    • However, the successful response assumes .result exists without validation
    • Recommendation: Add validation or optional chaining: return (await response.json())?.result;
  4. Plain SDK Guard (waitForClerk.ts:38)

    • Good addition of typeof Plain !== "undefined" check
    • However, the optional chaining Plain?.setCustomerDetails is redundant after the typeof check
    • Recommendation: Either use typeof check OR optional chaining, not both.

Performance Considerations 🚀

Positive Changes:

  1. Token caching by extracting to a function reduces redundant code (cloud-data-provider.tsx:342-348)
  2. Proper dependency array in useEffect prevents unnecessary worker re-initialization
  3. Use of useSyncExternalStore for efficient subscription management

Concerns:

  1. actor-worker-context.tsx:108-118 - Large dependency array could cause frequent re-renders

    • Consider using useRef for stable values or memoizing token functions
    • The engineToken function recreation on every render could be optimized
  2. words.ts - Massive reduction from ~1300 lines to ~150 lines (great!)

    • Simplification is excellent for bundle size and performance

Security Concerns 🔒

  1. Token Handling - Generally good practices:

    • Tokens are passed through headers correctly
    • Authorization header properly formatted with Bearer scheme
    • Token functions allow for dynamic token retrieval (good for expiration handling)
  2. X-Rivet-Token Header (actor-repl.worker.ts:199)

    • Custom header for engine tokens
    • Ensure this is properly sanitized on the backend
  3. REPL Code Execution (actor-repl.worker.ts:73-81)

    • Creating functions from user input using new Function()
    • This is properly isolated in a Web Worker
    • Window object is stubbed out with empty object {}
    • "use strict" mode enabled ✅
    • Good security posture, but ensure backend validates action calls
  4. Actor Inspector Token - New token type introduced

    • Metadata field inspectorToken retrieved from runner (actor-worker-context.tsx:42)
    • Should verify this field is properly secured on the backend

Test Coverage 🧪

Observations:

  • No test files modified in this PR
  • Changes involve complex async flows and worker communication
  • Recommendation: Consider adding tests for:
    • Token function resolution (both sync and async)
    • Worker initialization and message passing
    • Error handling paths (network failures, invalid tokens)
    • Empty/undefined runner name handling

Additional Notes 📝

  1. Breaking Change in Response Format (actor.ts:61-67)

    • Response now returns { state, enabled } instead of just the state
    • Good that it's handled consistently in onSuccess
    • Ensure all consumers expect this format
  2. Dependency Changes

    • Removed vendor packages (rivetkit-actor.tgz, rivetkit-core.tgz)
    • Switched to npm registry packages (good for maintainability)
    • pnpm-lock.yaml shows clean dependency resolution
  3. Unused Import Removed (cloud-data-provider.tsx:3)

    • FetchFunction import removed but not used - good cleanup

Summary

Overall Assessment: Good PR with minor improvements needed

The changes successfully fix the inspector functionality with solid architecture. Main concerns are around:

  1. Error handling for token resolution
  2. Type safety improvements
  3. Adding test coverage for critical paths

Recommended Actions:

  1. Add error handling around token function calls
  2. Consider adding unit tests for worker communication
  3. Validate backend security for inspector tokens
  4. Minor refactoring for type safety (avoid as string assertions)

The PR is in good shape and demonstrates solid understanding of async patterns, security considerations, and React best practices. The reduction in the words.ts file is particularly nice for bundle size!

@jog1t jog1t force-pushed the 10-20-fix_make_inspector_working_again branch from 2013347 to 7074439 Compare October 21, 2025 18:47
@jog1t jog1t marked this pull request as ready for review October 21, 2025 18:48
@jog1t jog1t requested a review from NathanFlurry October 21, 2025 18:48
@graphite-app graphite-app bot changed the base branch from cloud-hotfix to graphite-base/3229 October 21, 2025 18:49
@graphite-app graphite-app bot force-pushed the graphite-base/3229 branch from 725df55 to ca4eed0 Compare October 21, 2025 18:50
@graphite-app graphite-app bot force-pushed the 10-20-fix_make_inspector_working_again branch from 7074439 to cbaa3ff Compare October 21, 2025 18:50
@claude
Copy link

claude bot commented Oct 21, 2025

PR Review: Fix Inspector Functionality

Overview

This PR fixes the inspector functionality by properly handling authentication tokens and inspector credentials across different app types (engine vs inspector). The changes reduce code bloat (1403 deletions vs 299 additions) while fixing critical functionality.


✅ Positive Aspects

  1. Token Management Improvements

    • Properly handles async token resolution in actor-worker-container.ts:144-147
    • Tokens are now awaited when they're functions, preventing potential race conditions
    • Adds inspectorToken to the worker initialization flow
  2. Better Type Safety

    • Added proper return type for state patch mutation in actor.ts:61-64
    • The mutation now correctly types the response with { state: unknown; enabled: boolean }
  3. Code Simplification

    • Massive reduction in word list (words.ts) - from heroes to tools/adjectives, much more maintainable
    • Cleaner token handling by extracting the token function in cloud-data-provider.tsx:342-348
  4. Proper Data Flow

    • Inspector token properly flows through: context → worker container → worker → API calls
    • Pattern matching with ts-pattern ensures proper token headers based on __APP_TYPE__

⚠️ Issues & Concerns

🔴 Critical Issues

  1. Missing Runner Null Check (actor-worker-context.tsx:68)

    const inspectorToken = useInspectorToken(runner || "");

    Problem: If runner is undefined/null, this passes an empty string to useInspectorToken, which will:

    • In engine mode: make a query with runnerName: ""
    • Potentially fail silently or return incorrect data

    Recommendation: Add proper null handling:

    const inspectorToken = runner ? useInspectorToken(runner) : undefined;
  2. Unsafe Type Assertion (actor-worker-context.tsx:42)

    return (data?.metadata?.inspectorToken as string) || "";

    Problem: Using as string when the actual type is unknown. If inspectorToken is not a string, this could cause runtime errors.

    Recommendation: Add runtime validation:

    const token = data?.metadata?.inspectorToken;
    return typeof token === 'string' ? token : "";
  3. Query Made Before Data Availability (actor-worker-context.tsx:36-40)

    const { data } = useQuery(
      provider.runnerByNameQueryOptions({
        runnerName,
      }),
    );

    Problem: This query runs even when runnerName is empty string. Should be conditionally enabled.

    Recommendation:

    const { data } = useQuery({
      ...provider.runnerByNameQueryOptions({ runnerName }),
      enabled: !!runnerName,
    });

🟡 Medium Priority Issues

  1. Error Handling in Worker (actor-repl.worker.ts:210-216)

    if (!response.ok) {
      try {
        return await response.json();
      } catch {
        return await response.text();
      }
    }

    Problem: On error, you're returning the error body but not throwing. This means the caller receives error data as if it were a successful result.

    Recommendation: Throw the error:

    if (!response.ok) {
      let errorBody;
      try {
        errorBody = await response.json();
      } catch {
        errorBody = await response.text();
      }
      throw new Error(\`API Error: \${errorBody}\`);
    }
  2. Mutation Not Awaited (actor-editable-state.tsx:87)

    onClick={async () => {
      await mutateAsync(JSON.parse(value || ""));
      setIsEditing(false);
      setValue(null);
    }}

    Good: The mutation is now awaited! But there's no error handling.

    Recommendation: Add try-catch:

    onClick={async () => {
      try {
        await mutateAsync(JSON.parse(value || ""));
        setIsEditing(false);
        setValue(null);
      } catch (error) {
        // Handle error - show toast, keep editing mode, etc.
        console.error('Failed to update actor state:', error);
      }
    }}
  3. Missing Runner Field (default-data-provider.tsx:311)

    runner: data.runner ?? undefined,

    Issue: This is added to the data transformation, but we need to verify the source data.runner actually exists in the API response. If it doesn't, this will always be undefined.

🔵 Minor Issues

  1. Console.error Ordering (actor-worker-container.ts:243)

    • Moving the console.error before the if-check is good for debugging, but the message format could be improved
    • Consider: console.error("Actor Worker Error:", msg.type, msg.data);
  2. Plain SDK Check (waitForClerk.ts:38)

    if (typeof Plain !== "undefined") {
      Plain?.setCustomerDetails({...});
    }

    Good defensive coding, but the ?. is redundant after the typeof check.

    Minor improvement:

    if (typeof Plain !== "undefined") {
      Plain.setCustomerDetails({...});
    }
  3. Word List Changes (words.ts)

    • The new word list is much shorter and more focused
    • However, consider if the reduction from ~1300 to ~150 entries increases collision risk for generated keys
    • Assuming collision risk is acceptable, this is a huge improvement

🔒 Security Considerations

  1. Token Exposure in Headers (actor-repl.worker.ts:186-203)

    • Tokens are properly sent via headers (good)
    • Using Authorization: Bearer pattern correctly
    • Inspector token conditionally included based on presence
    • Engine token uses custom header X-Rivet-Token
    • No obvious security issues, but ensure tokens are not logged
  2. Token Storage

    • Tokens are passed through context and not stored in localStorage within this PR
    • ✅ Good practice
  3. Worker Scope

    • Web Worker has limited access to DOM/APIs
    • Token is passed into worker for API calls
    • ✅ Reasonable isolation

🚀 Performance Considerations

  1. Token Resolution - Now properly async, won't block rendering

  2. useEffect Dependencies (actor-worker-context.tsx:108-118)

    • All necessary dependencies included
    • Worker will reinitialize when tokens change - this could be expensive
    • Consider: If tokens change frequently, this might cause excessive worker restarts
    • Recommendation: Add stability check if token reference changes but value doesn't
  3. Query Optimizations


📝 Best Practices & Style

  1. Imports: Properly organized at top of files
  2. Logging: Uses structured logging with tracing patterns in most places
  3. Error Messages: Clear and descriptive
  4. ⚠️ Comments: The comment in actor-repl.worker.ts:182-184 is helpful
  5. Naming: Variable names are clear and consistent

🧪 Test Coverage

Concern: No test files are included in this PR. Given the complexity of the token flow and worker communication, consider adding tests for:

  1. Token resolution (sync vs async vs function)
  2. Worker initialization with different app types
  3. Inspector token retrieval with missing runner
  4. Error cases in API calls

📋 Summary

Recommendation: 🟡 Request Changes

The PR successfully fixes the inspector functionality and improves code organization. However, there are 3 critical issues that should be addressed before merge:

  1. Handle null/undefined runner properly
  2. Add runtime type validation for inspectorToken
  3. Enable query only when runnerName is available

The medium-priority issues (error handling in worker, mutation error handling) should also be addressed for production robustness.

Estimated Risk: Medium - Core functionality works but edge cases could cause issues


Great work on the token flow refactoring! The architecture is much cleaner. Once the critical issues are addressed, this will be a solid improvement. 🎉


Reviewed by Claude Code

@graphite-app
Copy link
Contributor

graphite-app bot commented Oct 21, 2025

Graphite Automations

"Test" took an action on this PR • (10/21/25)

1 assignee was added to this PR based on Kacper Wojciechowski's automation.

@graphite-app graphite-app bot changed the base branch from graphite-base/3229 to main October 21, 2025 18:50
@graphite-app graphite-app bot force-pushed the 10-20-fix_make_inspector_working_again branch from cbaa3ff to ce7ecee Compare October 21, 2025 18:50
@claude
Copy link

claude bot commented Oct 21, 2025

Pull Request Review: Fix Inspector Functionality

Summary

This PR fixes the actor inspector functionality by resolving authentication and data flow issues. The changes primarily focus on properly passing tokens and metadata through the data provider chain to enable inspector API calls from web workers.

Code Quality & Best Practices

✅ Strengths

  1. Proper async/await handling: The mutation in actor-editable-state.tsx:87-90 now correctly uses await mutateAsync() instead of mutate(), ensuring the UI state is only updated after the mutation completes.

  2. Token abstraction: Extracting the token function in cloud-data-provider.tsx:342-348 improves code reusability and reduces duplication.

  3. Type safety improvements: The mutation response in actor.ts:61-64 now has explicit typing, making the contract clearer.

  4. Separation of concerns: The PR properly separates inspector token handling from engine tokens using pattern matching.

⚠️ Areas for Improvement

  1. Missing error handling in async setupWorker (actor-worker-container.ts:122)

    async #setupWorker(worker: Worker) {
        // ... 
        engineToken:
            typeof this.#meta?.engineToken === "function"
                ? await this.#meta?.engineToken()
                : this.#meta?.engineToken,

    Issue: If engineToken() throws, this could crash the worker setup without proper error handling.

    Recommendation: Add try-catch or handle the promise rejection:

    engineToken:
        typeof this.#meta?.engineToken === "function"
            ? await this.#meta?.engineToken().catch((e) => {
                console.error("Failed to fetch engine token:", e);
                return "";
            })
            : this.#meta?.engineToken ?? "",
  2. Type inconsistency (engine-data-provider.tsx:59)

    engineToken: (() => string) | string | (() => Promise<string>);

    Issue: Having three different types for the same field makes the code harder to reason about and could lead to runtime errors.

    Recommendation: Normalize to always use () => Promise<string> for consistency, or use a discriminated union.

  3. Unsafe type assertion (actor-worker-context.tsx:42)

    return (data?.metadata?.inspectorToken as string) || "";

    Issue: Type assertion bypasses type safety. If inspectorToken is not a string, this could cause issues.

    Recommendation: Use type guard or validate the type:

    const token = data?.metadata?.inspectorToken;
    return typeof token === "string" ? token : "";

Potential Bugs

  1. Race condition in useInspectorToken (actor-worker-context.tsx:36-40)

    const { data } = useQuery(
        provider.runnerByNameQueryOptions({
            runnerName,
        }),
    );

    Issue: If runnerName is empty string, this will still execute the query. The hook is called with runner || "" on line 68.

    Recommendation: Add enabled flag:

    const { data } = useQuery({
        ...provider.runnerByNameQueryOptions({ runnerName }),
        enabled: !!runnerName,
    });
  2. Missing null checks in worker (actor-repl.worker.ts:177-218)
    The callAction function doesn't validate init.endpoint exists before using it in new URL().

    Recommendation: Add validation:

    if (!init?.endpoint) throw new Error("Endpoint not configured");

Performance Considerations

  1. Word list optimization (words.ts) - ✅ Excellent improvement!

    • Reduced from 1,403 lines to 299 lines (~79% reduction)
    • Changed from superhero names to simpler adjective-tool combinations
    • This will reduce bundle size and improve load times
  2. Unnecessary re-renders (actor-worker-context.tsx:108-118)
    The dependency array is quite large. Consider using useMemo for compound dependencies or reducing the number of reactive values.

Security Concerns

  1. Token exposure in headers (actor-repl.worker.ts:186-203)

    headers: {
        Authorization: init.inspectorToken ? `Bearer ${init.inspectorToken}` : "",
        "X-Rivet-Token": init.engineToken ? init.engineToken : "",

    Good: Tokens are properly set in Authorization headers
    ⚠️ Concern: Ensure these tokens have appropriate scopes and are not over-privileged

    Recommendation: Document the required token scopes/permissions in code comments

  2. Error message leakage (actor-repl.worker.ts:210-215)

    if (!response.ok) {
        try {
            return await response.json();
        } catch {
            return await response.text();
        }
    }

    Issue: Returning raw error responses to the client could leak sensitive information

    Recommendation: Sanitize error messages before returning to the client

Test Coverage

Missing: This PR doesn't include any test changes or additions.

Recommendations:

  1. Add unit tests for the new token handling logic
  2. Add integration tests for the inspector worker flow
  3. Test the async token resolution paths
  4. Test error cases (missing tokens, invalid tokens, network failures)

Additional Observations

  1. Plain SDK optional check (waitForClerk.ts:38-42) - ✅ Good defensive programming

    if (typeof Plain !== "undefined") {
        Plain?.setCustomerDetails({...});
    }
  2. Deleted vendor files - Files frontend/vendor/rivetkit-actor.tgz and rivetkit-core.tgz were removed. Ensure these are now properly sourced from npm/package registry.

  3. Railway env vars reordering (connect-railway-frame.tsx:179-182) - Minor change to reorder environment variables. Ensure documentation is updated if this order matters.

Summary Recommendations

Critical

  • Add error handling for async engineToken() resolution
  • Add validation for init.endpoint before creating URL
  • Add enabled flag to useInspectorToken query

Important

  • Fix type assertion for inspectorToken
  • Add test coverage for authentication flow
  • Document token scope requirements

Nice to Have

  • Normalize engineToken type to single async function type
  • Optimize dependency array in worker context
  • Add error message sanitization

Verdict

This is a solid fix that addresses the core inspector issues. The code quality is generally good with proper async handling and token management. However, there are some error handling gaps and potential race conditions that should be addressed before merging to production.

Recommendation: Approve with requested changes for error handling and null checks.


Review generated with Claude Code

@claude
Copy link

claude bot commented Oct 21, 2025

Code Review - PR #3229: fix: make inspector working again

Overview

This PR fixes the inspector functionality by updating token handling, authentication flow, and improving the actor worker/REPL integration. The changes primarily focus on frontend TypeScript code related to actor inspection and data providers.


✅ Strengths

  1. Improved Token Management: The refactoring to pass engineToken as a function (supporting both sync and async) is more flexible and allows for dynamic token fetching.

  2. Better Type Safety: Added proper type definitions for response structures (e.g., actor.ts:61-64).

  3. Cleaner Code Organization: Extracting the token function in cloud-data-provider.tsx:342-348 improves readability and reusability.

  4. Bug Fix for Plain Integration: The defensive check for Plain in waitForClerk.ts:38 prevents runtime errors when Plain is not defined.


🔍 Issues & Recommendations

1. Security Concern: Token Handling in Worker (HIGH PRIORITY)

Location: actor-repl.worker.ts:177-219 and actor-worker-container.ts:122-152

The worker receives and stores the raw token value after resolving it:

engineToken:
    typeof this.#meta?.engineToken === "function"
        ? await this.#meta?.engineToken()
        : this.#meta?.engineToken,

Issues:

  • The token is serialized and sent to the web worker via postMessage, which stores it in the worker context
  • If the token expires or rotates, the worker will continue using the stale token
  • No refresh mechanism exists for tokens in the worker

Recommendation:

  • Consider passing a message-based token fetching mechanism where the worker requests a fresh token from the main thread when needed, rather than storing it
  • Alternatively, implement token refresh logic with expiration checking

2. Error Handling Issues

Location: actor-repl.worker.ts:210-216

if (!response.ok) {
    try {
        return await response.json();
    } catch {
        return await response.text();
    }
}

Issues:

  • Returns error response data directly without throwing or proper error signaling
  • The calling code may not distinguish between successful and error responses
  • Silent catch block with no logging

Recommendation:

if (!response.ok) {
    let errorMsg: string;
    try {
        const errorData = await response.json();
        errorMsg = errorData.message || JSON.stringify(errorData);
    } catch {
        errorMsg = await response.text();
    }
    throw new Error(`Action failed: ${errorMsg}`);
}

3. Race Condition in Actor Initialization

Location: actor-worker-container.ts:80-82

if (this.#meta.actorId !== meta.actorId) {
    // if not, we don't need to do anything
    return null;
}

Issue: This check happens after async operations, but this.#meta could be modified by another concurrent init() call.

Recommendation:

  • Use a unique initialization ID or AbortController-based cancellation
  • Consider making init() reject concurrent calls explicitly

4. Missing Null/Undefined Checks

Location: actor-worker-context.tsx:68 and default-data-provider.tsx:310

In actor-worker-context.tsx:68, the code uses:

const inspectorToken = useInspectorToken(runner || "");

Issue: If runner is undefined, it passes empty string which triggers the query unnecessarily.

Recommendation:

const inspectorToken = useInspectorToken(runner);
// And update useInspectorToken to handle undefined:
const useInspectorToken = (runnerName: string | undefined) => {
    return match(__APP_TYPE__)
        .with("inspector", () => {
            return useInspectorCredentials().credentials?.token;
        })
        .otherwise(() => {
            const provider = useEngineCompatDataProvider();
            const { data } = useQuery({
                ...provider.runnerByNameQueryOptions({ runnerName }),
                enabled: !!runnerName, // Add this
            });
            return (data?.metadata?.inspectorToken as string) || "";
        });
};

5. Type Safety Issue

Location: actor-worker-context.tsx:42

return (data?.metadata?.inspectorToken as string) || "";

Issue: Using type assertion without validation. If inspectorToken is not a string, this could cause runtime issues.

Recommendation:

return typeof data?.metadata?.inspectorToken === 'string' 
    ? data.metadata.inspectorToken 
    : "";

6. Async Function Not Awaited

Location: actor-worker-container.ts:122

async #setupWorker(worker: Worker) {

This function is async but the await happens inside for engineToken. The function is called without await in actor-worker-container.ts:88:

this.#setupWorker(worker);

Issue: Potential race condition where initialization may not complete before worker is used.

Recommendation: Either await the #setupWorker call or make it synchronous and handle async token fetching differently.


7. Missing Error Logging

Location: actor-worker-container.ts:92

} catch (e) {
    console.log(e);  // Should be console.error

Recommendation: Use console.error for errors, or better yet, use structured logging if available.


8. Console Error Moved But Information Lost

Location: actor-worker-container.ts:243

The error logging was moved but the context message was removed:

console.error("Actor Worker Error", msg);
if (!msg.id) {
    this.#state.status = { type: "error", error: msg.data };
    // Old code had: console.error("Actor Worker Error", msg.data);

Recommendation: Keep detailed error logging for debugging purposes.


📝 Minor Issues

  1. Inconsistent Error Message Casing (actor.ts:34): Changed from async call pattern but mutation is now awaited in component. Consider documenting this pattern change.

  2. Unused Import: actor-queries.ts:3 removes applyPatch import but compare is still used - good cleanup.

  3. Words File Simplification: The massive reduction in words.ts from hero names to tool names is a good simplification, though it's unclear if this is intentional or related to the inspector fix.


🧪 Test Coverage Concerns

No test files are included in this PR. Consider adding tests for:

  • Token refresh/expiration scenarios
  • Worker initialization race conditions
  • Error handling paths in the REPL worker
  • Inspector token fetching for different app types

✨ Suggestions for Future Improvements

  1. Token Refresh Strategy: Implement automatic token refresh before expiration
  2. Worker Lifecycle Management: Add explicit state machine for worker states
  3. Structured Logging: Replace console.log/error with proper logging framework
  4. Error Boundaries: Add React error boundaries around actor worker components

Summary

The PR successfully fixes the inspector functionality with good architectural improvements in token handling. However, there are several security, error handling, and race condition concerns that should be addressed before merging.

Recommendation: Request changes to address the high-priority security concern around token handling in workers and the error handling issues. The other issues can be addressed as follow-up improvements.

Priority Fixes Needed:

  1. ⚠️ Token refresh mechanism in workers
  2. ⚠️ Proper error handling in callAction
  3. ⚠️ Race condition protection in init()
  4. Missing null checks for runner-based token fetching

🤖 Generated with Claude Code

@claude
Copy link

claude bot commented Oct 21, 2025

PR Review: fix: make inspector working again

Summary

This PR fixes the inspector functionality with 18 files changed (+299/-1403 lines). The changes primarily focus on fixing authentication and token handling for the actor inspector, along with a significant simplification of the word list.

Positives ✅

  1. Good separation of concerns: The token extraction in cloud-data-provider.tsx:342-350 properly separates the async token function for reusability
  2. Proper error handling: The worker error handling in actor-worker-container.ts:242-248 correctly logs errors before state updates
  3. Type safety improvements: Added proper return type for useActorStatePatchMutation in actor.ts:61-64
  4. Defensive programming: Added typeof Plain !== "undefined" check in waitForClerk.ts:38 to prevent runtime errors
  5. Code cleanup: Massive simplification of word lists (1292 → 151 entries) makes the code more maintainable

Issues & Concerns 🔴

Critical Issues

  1. Async/await inconsistency in actor-worker-context.tsx:122

    async #setupWorker(worker: Worker) {
        // ... async operations
        this.#worker.postMessage({
            engineToken: typeof this.#meta?.engineToken === "function"
                ? await this.#meta?.engineToken()
                : this.#meta?.engineToken,

    The method is async and uses await, but the caller at line 88 doesn't await it: this.#setupWorker(worker);. This could cause race conditions where the worker isn't fully initialized before being used.

  2. Potential race condition in useInspectorToken (actor-worker-context.tsx:29-44)

    const useInspectorToken = (runnerName: string) => {
        return match(__APP_TYPE__)
            .otherwise(() => {
                const { data } = useQuery(
                    provider.runnerByNameQueryOptions({ runnerName }),
                );
                return (data?.metadata?.inspectorToken as string) || "";
            });
    };

    The query might not have completed when this value is used. No loading state is checked before accessing data.

  3. Type casting without validation (actor-worker-context.tsx:42)

    return (data?.metadata?.inspectorToken as string) || "";

    Type assertion without runtime validation. If inspectorToken is not a string, this could cause issues downstream.

Medium Priority Issues

  1. Missing error boundary in actor-repl.worker.ts:210-216

    if (!response.ok) {
        try {
            return await response.json();
        } catch {
            return await response.text();
        }
    }

    The error return doesn't distinguish between JSON parse failures and actual API errors. Consider logging or handling these differently.

  2. Hardcoded authentication header logic (actor-repl.worker.ts:186-202)
    The authentication logic with match(__APP_TYPE__) pattern is duplicated across multiple files. Consider extracting to a shared utility function.

  3. Incomplete useEffect dependencies
    In actor-worker-context.tsx:87-118, the effect depends on engineToken which could be a function. If the function reference changes, it will trigger re-initialization unnecessarily.

Minor Issues

  1. console.log in production code (actor-worker-container.ts:92)

    } catch (e) {
        console.log(e);

    Should use proper logging framework or at least console.error.

  2. Mutation response handling (actor-editable-state.tsx:87)

    await mutateAsync(JSON.parse(value || ""));

    The mutation result is not checked. If it fails, setIsEditing(false) still executes.

  3. Missing null/empty string validation
    In actor-worker-context.tsx:68: const inspectorToken = useInspectorToken(runner || "");
    Passing empty string to useInspectorToken when runner is falsy could trigger unnecessary queries.

Security Considerations 🔒

  1. Token handling: Tokens are now properly passed through headers rather than query strings ✅
  2. Authorization header construction: Properly uses Bearer token format ✅
  3. Consider: Add token expiration/refresh handling if not already present elsewhere

Performance Considerations ⚡

  1. Positive: Word list reduction significantly reduces bundle size
  2. Concern: The useInspectorToken hook could trigger queries even when not needed (when runner is empty)
  3. Concern: structuredClone(data) in actor-repl.worker.ts:117 creates deep copies - ensure this is necessary for the data size

Testing & Coverage 🧪

⚠️ No test files modified or added

Given the complexity of authentication and worker initialization changes, I recommend adding:

  • Unit tests for token resolution logic
  • Integration tests for worker initialization flow
  • Tests for error scenarios (invalid tokens, failed queries, etc.)

Recommendations 📋

  1. High Priority: Fix the async/await issue in #setupWorker ([SVC-2555] Set up issue templates #1)
  2. High Priority: Add loading/error state checks for useInspectorToken ([SVC-2479] Send cluster events to PostHog #2)
  3. Medium Priority: Extract authentication header logic to shared utility
  4. Medium Priority: Add proper error handling for mutation failures
  5. Low Priority: Replace console.log with proper logging
  6. Add tests: Cover the authentication flow and worker initialization

Additional Notes

  • The PR title says "make inspector working again" - consider documenting what broke it initially in the PR description for future reference
  • The vendor package updates (rivetkit-actor.tgz, rivetkit-core.tgz removal) suggest dependency management changes - ensure these are intentional

Overall, this PR addresses important functionality issues but has some async/await and error handling gaps that should be addressed before merging.

🤖 Generated with Claude Code

@graphite-app
Copy link
Contributor

graphite-app bot commented Oct 22, 2025

Merge activity

  • Oct 22, 6:58 AM UTC: This pull request can not be added to the Graphite merge queue. Please try rebasing and resubmitting to merge when ready.
  • Oct 22, 6:58 AM UTC: Graphite disabled "merge when ready" on this PR due to: a merge conflict with the target branch; resolve the conflict and try again..

@claude
Copy link

claude bot commented Oct 24, 2025

PR Review: Fix Inspector Integration

Summary

This PR fixes the actor inspector functionality by properly integrating authentication tokens and inspector client configuration. The changes touch multiple areas including data providers, actor worker integration, and utility functions.


Code Quality & Architecture

✅ Strengths

  1. Token Management: The refactoring to expose engineToken through the data provider hierarchy is well-designed and follows the existing architectural patterns.
  2. Type Safety: Good use of TypeScript with proper typing for the Meta interface in actor-worker-container.ts:36-45.
  3. Error Handling: The worker properly handles both successful and error responses in actor-repl.worker.ts:210-216.
  4. Defensive Programming: The Plain undefined check in waitForClerk.ts:38 is a good defensive measure.

🔍 Areas for Improvement

1. Async/Await Inconsistency (actor-worker-container.ts:122)
The #setupWorker method is marked as async but the await is only used for a single operation at the end. Consider making the await more explicit:

async #setupWorker(worker: Worker) {
  this.#worker = worker;
  // ... event listeners setup ...
  
  // Clearly separate async token resolution
  const engineToken = typeof this.#meta?.engineToken === "function"
    ? await this.#meta.engineToken()
    : this.#meta?.engineToken;
  
  this.#worker.postMessage({
    // ... other fields ...
    engineToken,
    // ...
  } satisfies InitMessage);
}

2. Potential Race Condition (actor-worker-context.tsx:87-118)
The useEffect dependencies are extensive, and there's a potential for the container to be re-initialized frequently. Consider:

  • Using useMemo for stable object references
  • Reducing dependency array items by grouping related values
  • Adding a comment explaining why all these dependencies are necessary (the biome-ignore is noted but could be more detailed)

3. Error Logging (actor-worker-container.ts:92)
The generic console.log(e) should use console.error for consistency and proper log levels:

catch (e) {
  console.error("Actor initialization error:", e);
  // ...
}

Security Concerns

⚠️ Medium Priority

1. Token Exposure in Web Workers (actor-repl.worker.ts:177-219)
The callAction function constructs headers with tokens that are passed through structuredClone and stored in the worker context. While web workers are isolated, ensure:

  • Tokens are not logged or exposed through error messages
  • The worker is properly terminated when no longer needed (✅ this appears to be handled in terminate())

2. Header Construction (actor-repl.worker.ts:185-204)
The conditional header construction based on __APP_TYPE__ is good, but the Authorization header always includes the inspector token even if empty:

Authorization: init.inspectorToken ? `Bearer ${init.inspectorToken}` : "",

Consider only adding the header when the token exists:

...(init.inspectorToken ? { Authorization: `Bearer ${init.inspectorToken}` } : {}),

Potential Bugs

🐛 Issues Found

1. Missing Null Check (actor-worker-context.tsx:68)
The useInspectorToken is called with runner || "", but if runner is undefined/null and we're not in inspector mode, this could cause unnecessary queries:

const inspectorToken = useInspectorToken(runner || "");

Consider adding a conditional:

const inspectorToken = runner ? useInspectorToken(runner) : "";

2. Type Coercion (actor-worker-context.tsx:42)
The type assertion (data?.metadata?.inspectorToken as string) || "" could mask type issues. Consider using proper type narrowing or optional chaining with nullish coalescing:

return data?.metadata?.inspectorToken ?? "";

3. Mutation Return Type (actor-editable-state.tsx:49,87)
The mutation is changed to mutateAsync but there's no error handling for the async operation:

onClick={async () => {
  await mutateAsync(JSON.parse(value || ""));
  setIsEditing(false);
  setValue(null);
}}

Should wrap in try-catch:

onClick={async () => {
  try {
    await mutateAsync(JSON.parse(value || ""));
    setIsEditing(false);
    setValue(null);
  } catch (error) {
    console.error("Failed to patch actor state:", error);
    // Consider showing user feedback
  }
}}

Performance Considerations

⚡ Observations

1. Token Fetching (cloud-data-provider.tsx:342-348)
The token function is defined but will be called multiple times. The queryClient.fetchQuery will handle caching, but ensure the staleTime and gcTime in accessTokenQueryOptions are appropriate (✅ they are set to 15 minutes in line 310-311).

2. Words.ts Optimization (words.ts:1-151)
Replacing the large "heroes" array with a smaller "tools" array significantly reduces bundle size (from ~1,315 lines to ~151 lines). This is an excellent optimization! 👍

The new word combinations (adjective-tool like "bright-hammer", "sharp-saw") are:

  • More professional and appropriate for a technical platform
  • Shorter and more memorable
  • Better aligned with the product's technical nature

Test Coverage

📋 Recommendations

Missing Test Coverage:

  1. Actor Worker Token Handling: Test token resolution for both sync and async engineToken functions
  2. Inspector Token Flow: Test the full flow from data provider to worker initialization
  3. Error States: Test worker behavior when tokens are invalid or missing
  4. Railway Dialog: The env variable order change should be tested to ensure correct functionality

Suggested Test Cases:

// Example test structure
describe('ActorWorkerContainer', () => {
  it('should handle async token resolution', async () => {
    const asyncToken = async () => 'test-token';
    // Test initialization with async token
  });
  
  it('should handle missing inspector token gracefully', () => {
    // Test with undefined/null runner
  });
});

Additional Observations

📝 Minor Issues

1. Removed Vendor Files
The PR removes frontend/vendor/rivetkit-actor.tgz and frontend/vendor/rivetkit-core.tgz. Ensure these are now properly managed through npm/pnpm dependencies.

2. Import Cleanup (cloud-data-provider.tsx:3)
Good removal of unused FetchFunction import.

3. Railway Dialog Order (connect-railway-frame.tsx:180-181)
The order of RivetNamespaceEnv and RivetTokenEnv was swapped. Verify this is intentional and that any dependent logic handles this correctly.

4. Connect Route Cleanup (connect.tsx)
The file shows 8 deletions with 0 additions - ensure this doesn't break any navigation or functionality.


Final Recommendations

Priority Actions:

  1. High: Add error handling to the mutateAsync call in actor-editable-state.tsx
  2. High: Add null check before calling useInspectorToken with runner
  3. Medium: Fix error logging level in actor-worker-container.ts
  4. Medium: Improve authorization header construction to only include when token exists
  5. Low: Consider extracting token resolution logic to a separate utility function for reusability

Before Merging:

  • ✅ Verify all token flows work in both Cloud and Engine environments
  • ✅ Test inspector functionality with and without valid tokens
  • ✅ Ensure vendor package removals don't break builds
  • ✅ Confirm Railway integration still works with reordered env variables
  • ⚠️ Add integration tests for the actor worker initialization flow
  • ⚠️ Document the token flow in code comments for future maintainers

Conclusion

This is a solid PR that fixes critical inspector functionality. The architecture improvements for token management are well-designed. The main concerns are around error handling and potential race conditions, which should be addressed before merging. The words.ts optimization is a nice bonus that improves bundle size!

Overall Assessment: ✅ Approve with minor changes recommended

Great work on tracking down and fixing the inspector integration! 🎉

@claude
Copy link

claude bot commented Oct 24, 2025

PR Review: Fix Inspector Functionality

Summary

This PR fixes the actor inspector functionality by properly handling authentication tokens and improving the actor REPL worker. The changes are well-structured and address critical functionality issues.

✅ Strengths

  1. Authentication Flow Improvements: The PR correctly threads inspector tokens and engine tokens through the worker chain, fixing authentication issues that were preventing the inspector from working.

  2. Async Token Handling: Good addition of support for async token retrieval functions in actor-worker-container.ts:144-147, which properly handles both sync and async token providers.

  3. Type Safety Improvements: Enhanced type definitions in actor.ts:61-64 with explicit return type for the mutation response.

  4. Error Handling: Better error handling in the worker with proper logging (actor-worker-container.ts:243).

  5. Code Organization: The refactoring separates concerns well, particularly in how tokens are passed through different contexts.

🔍 Issues & Concerns

Critical

  1. Token Security in Worker (actor-repl.worker.ts:177-219)

    • The inspector token and engine token are being passed to a web worker and stored in plain text
    • Tokens are sent in headers without additional validation
    • Consider the security implications of exposing tokens to the worker context
    • Recommendation: Document the security model and ensure tokens have appropriate scoping
  2. Async Function Not Awaited (actor.ts:34 and actor.ts:150)

    • queries.createActorInspector(actorId) is called with await, but in line 150 of actor.ts it's used without await in a useMemo
    • This inconsistency suggests the function signature may have changed
    • Recommendation: Verify if createActorInspector should always be async or if it can be sync in some cases
  3. Conditional Inspector Token Hook (actor-worker-context.tsx:29-44)

    • The useInspectorToken hook conditionally uses different data providers based on app type
    • The otherwise branch fetches runner data that may not be loaded yet, potentially returning an empty string
    • Recommendation: Add loading state handling and error boundaries for when runner data isn't available

Medium Priority

  1. Missing Runner Field Validation (default-data-provider.tsx:311)

    • The runner field is added with ?? undefined, but there's no validation that this field exists in the data
    • Recommendation: Add null checks or default values in case the API response doesn't include runner info
  2. Plain Check Undefined (waitForClerk.ts:38)

    • The check if (typeof Plain !== "undefined") is good, but the optional chaining Plain?.setCustomerDetails is redundant
    • Recommendation: Remove the optional chaining since you've already checked for undefined
  3. Dependency Array Complexity (actor-worker-context.tsx:108-118)

    • The useEffect has 9 dependencies, making it prone to unnecessary re-renders
    • engineToken could be a function, causing re-initialization on every render
    • Recommendation: Consider memoizing the token resolver or splitting into multiple effects

Low Priority

  1. Console Logging (actor-worker-container.ts:92, 135)

    • Using console.log instead of proper logging (should use tracing based on CLAUDE.md)
    • Recommendation: Replace with tracing for consistency
  2. Words List Refactor (lib/words.ts)

    • Large deletion of heroes list replaced with tools list (1292 lines removed, 128 added)
    • This is good for simplification, but ensure this doesn't break existing name generation in production
    • Recommendation: Verify no existing systems depend on the old hero names

🎯 Best Practices

✅ Good use of TypeScript satisfies operator
✅ Proper structuredClone usage for deep copying
✅ Error handling with try-catch blocks
✅ Pattern matching with ts-pattern
✅ Proper cleanup in useEffect returns

🧪 Test Coverage

Missing: No test files included in this PR. Given the complexity of the authentication flow and worker communication:

Recommendations:

  • Add unit tests for token resolution logic
  • Add integration tests for the worker message passing
  • Test error scenarios (expired tokens, network failures)
  • Test the inspector token retrieval for both app types

🔒 Security Considerations

  1. Token Exposure: Tokens are being passed to web workers which operate in a different execution context. Ensure:

    • Workers are served from the same origin
    • Token scoping is appropriate for inspector operations
    • Consider token rotation/expiration policies
  2. Header Injection: The custom headers in actor-repl.worker.ts:186-203 should be validated server-side to prevent header injection attacks

🚀 Performance

  • The async token resolution in useEffect could cause performance issues if the token fetch is slow
  • Consider caching the resolved token to avoid repeated async calls
  • The worker initialization might benefit from a warmup pool pattern for frequently accessed actors

📝 Overall Assessment

Verdict: ✅ Approve with suggestions

This is a solid fix that addresses the core functionality issues. The main concerns are around security (token handling in workers) and the async/await inconsistencies. The refactoring improves code organization, but needs test coverage to ensure reliability.

Before merging:

  1. Clarify the async behavior of createActorInspector
  2. Add error handling for missing runner data
  3. Consider adding at least basic tests for the worker communication flow
  4. Replace console.log with tracing

Nice work on the authentication flow improvements! 🎉

@claude
Copy link

claude bot commented Oct 24, 2025

Pull Request Review: Fix Inspector Functionality

Overview

This PR fixes the inspector functionality by refactoring how actor worker initialization and authentication works. The changes appear to address issues with the actor inspector's ability to communicate with actors.

Code Quality & Best Practices

✅ Strengths

  1. Type Safety Improvements

    • Added proper typing for API responses in actor.ts:62-66
    • Clear interface definitions in actor-worker-container.ts:36-45
  2. Clean Refactoring

    • Simplified the words list (words.ts) from Marvel heroes to practical tool/adjective combinations - much more maintainable and scalable
    • Good use of structuredClone for deep copying initialization data (actor-repl.worker.ts:117)
  3. Better Async Handling

    • Properly awaiting mutateAsync instead of using mutate in actor-editable-state.tsx:88-90
    • Async token resolution properly handled in actor-worker-container.ts:144-147

⚠️ Potential Issues

  1. Missing Type Safety (actor-repl.worker.ts:177-219)

    async function callAction({ name, args }: { name: string; args: unknown[] }) {
    • The args parameter is typed as unknown[] but there's no validation
    • Error handling catches all errors but may swallow important error details (lines 210-215)
    • Recommendation: Add runtime validation or at least log detailed error information
  2. Unsafe Header Deletion (engine-data-provider.tsx:52-56)

    Object.keys(args.headers || {}).forEach((key) => {
      if (key.toLowerCase().startsWith("x-fern-")) {
        delete args.headers?.[key];  // Optional chaining after already accessing it
      }
    });
    • This is using optional chaining inconsistently. If args.headers exists (checked in the loop), the delete should work without optional chaining
    • Recommendation: Refactor to:
    if (args.headers) {
      Object.keys(args.headers).forEach((key) => {
        if (key.toLowerCase().startsWith("x-fern-")) {
          delete args.headers[key];
        }
      });
    }
  3. Hardcoded Empty String Fallback (actor-worker-context.tsx:42)

    return (data?.metadata?.inspectorToken as string) || "";
    • Type assertion followed by fallback could hide type issues
    • Recommendation: Add runtime validation or proper error handling if token is missing
  4. Console.log Left in Production Code (actor-worker-container.ts:92)

    console.log(e);
    • Should use proper logging or be removed for production
    • Recommendation: Use proper logging infrastructure or remove
  5. Dependency on Global __APP_TYPE__ (actor-repl.worker.ts:196)

    ...match(__APP_TYPE__)
      .with("engine", () => { ... })
      .otherwise(() => ({})),
    • Relying on global variables in workers can be fragile
    • Recommendation: Pass this as part of the initialization message

Performance Considerations

⚠️ Potential Concerns

  1. Token Function Resolution (actor-worker-container.ts:144-147)

    • Token is resolved on every worker setup, which happens frequently
    • If token fetching is expensive, consider caching strategy
    • The async/await in #setupWorker means token resolution blocks worker initialization
  2. useEffect Dependencies (actor-worker-context.tsx:108-118)

    • Large dependency array (8 dependencies) means worker will recreate frequently
    • Each recreation terminates and reinitializes the worker
    • Recommendation: Consider memoizing some values or reducing churn

Security Concerns

⚠️ Medium Priority

  1. Token Exposure in Headers (actor-repl.worker.ts:186-203)

    • Inspector token and engine token are passed in headers within a web worker
    • Headers are logged in error cases (line 243): console.error("Actor Worker Error", msg)
    • Recommendation: Ensure error messages don't leak sensitive headers in production
  2. Code Evaluation in Worker (actor-repl.worker.ts:48-82)

    • Using new Function() to evaluate user code is inherently risky
    • Although it's in a worker (isolated), it's still evaluating arbitrary code
    • The window object is explicitly blocked which is good
    • Recommendation: Document security model and ensure proper sandboxing at infrastructure level
  3. Missing Authorization Check (actor-repl.worker.ts:177)

    • No apparent validation that the user has permission to call actions
    • Token-based auth is present but no explicit permission checks
    • Recommendation: Verify authorization is handled by backend

Test Coverage

❌ Missing

  • No test files included in this PR
  • Changes to critical authentication/authorization paths should have tests
  • Recommendation: Add tests for:
    • Token resolution with various token types (string, function, async function)
    • Worker initialization with different configurations
    • Error handling paths in callAction
    • State mutation response handling

Additional Notes

  1. Removed Vendor Files

    • frontend/vendor/rivetkit-actor.tgz and rivetkit-core.tgz were removed
    • Ensure these are properly replaced via npm dependencies
  2. Plain SDK Safety (waitForClerk.ts:38-42)

    if (typeof Plain !== "undefined") {
      Plain?.setCustomerDetails({ ... });
    }
    • Good defensive programming for optional dependency
  3. Railway Environment Variables Order (connect-railway-frame.tsx:179-181)

    • Swapped order of RivetTokenEnv and RivetNamespaceEnv
    • Ensure this doesn't break any dependent code expecting specific order

Verdict

Approval with Recommendations: The core functionality looks solid and the refactoring improves maintainability. However, there are several areas that should be addressed:

Must Fix Before Merge:

  • Remove or replace console.log with proper logging
  • Add test coverage for authentication paths
  • Verify vendor package removal doesn't break dependencies

Should Fix Soon:

  • Improve error handling in callAction
  • Add runtime validation for inspector tokens
  • Review token caching strategy for performance

Consider for Future:

  • Reduce worker recreation frequency
  • Add comprehensive security documentation
  • Consider more robust sandboxing documentation

Great work on simplifying the words list and improving the async handling! 🚀

@claude
Copy link

claude bot commented Oct 24, 2025

Code Review: Fix Inspector Functionality

Thank you for working on fixing the inspector! I've reviewed the changes and have the following feedback:

✅ Positive Observations

  1. Clear Intent: The PR successfully addresses inspector functionality issues by properly passing authentication tokens and configuration through the worker context.

  2. Improved Type Safety: Good addition of explicit return type in actor.ts:62-66 for the mutation response, making the API contract clearer.

  3. Async/Await Handling: The change from mutate to mutateAsync in actor-editable-state.tsx:87-89 ensures proper sequencing when saving state.

  4. Better Token Management: Extracting the token function in cloud-data-provider.tsx:342-349 improves code organization and reduces duplication.

🔍 Potential Issues & Concerns

1. Error Handling in Worker (actor-repl.worker.ts:210-216)

if (\!response.ok) {
  try {
    return await response.json();
  } catch {
    return await response.text();
  }
}
  • ⚠️ Issue: When the response is not OK, you're returning the error but not throwing it. This means the caller won't know an error occurred.
  • Recommendation: Consider throwing an error or returning a structured error object that can be distinguished from success responses.

2. Unsafe Header Deletion (engine-data-provider.tsx:52-56)

Object.keys(args.headers || {}).forEach((key) => {
  if (key.toLowerCase().startsWith("x-fern-")) {
    delete args.headers?.[key];  // ⚠️ Using optional chaining on delete
  }
});
  • ⚠️ Issue: The optional chaining args.headers?.[key] on delete is unusual. If args.headers is already checked/defaulted above, this should be safe to use without optional chaining.
  • Recommendation: Either use delete args.headers[key] or add a type guard.

3. Missing Error Handling for Token Resolution

In actor-worker-container.ts:143-147:

engineToken:
  typeof this.#meta?.engineToken === "function"
    ? await this.#meta?.engineToken()
    : this.#meta?.engineToken,
  • ⚠️ Issue: If the token function throws, it will crash the worker initialization with no clear error message.
  • Recommendation: Wrap in try-catch with proper error handling.

4. Plain Global Type Safety (waitForClerk.ts:38)

if (typeof Plain \!== "undefined") {
  Plain?.setCustomerDetails({...});
}
  • ⚠️ Issue: After checking typeof Plain \!== "undefined", the optional chaining Plain? is redundant.
  • Recommendation: Use Plain.setCustomerDetails without optional chaining inside the if block.

5. Unused Import

In queries/actor.ts:3, you removed the import for applyPatch and Patch but they might be used elsewhere. Confirm these are truly unused.

6. Console Error Logging (actor-worker-container.ts:243)

console.error("Actor Worker Error", msg);
  • The error is logged but the error details from msg.data are logged as a separate parameter. Consider logging the full error object for better debugging.

🎯 Performance Considerations

  1. Token Resolution: The token function is now called on every worker initialization. Ensure this doesn't cause unnecessary API calls. Consider caching if appropriate.

  2. Re-renders: The useEffect dependencies in actor-worker-context.tsx:108-118 include many variables. Ensure these don't cause unnecessary worker recreations.

🔒 Security Concerns

  1. Token Exposure: Ensure inspector tokens are properly scoped and have appropriate expiration. The tokens are being passed through web workers which is generally safe, but verify they're not logged or exposed.

  2. Authorization Headers: The actor-repl.worker.ts:186-203 constructs authorization headers differently based on __APP_TYPE__. Verify both paths are secure and properly authenticated.

📝 Code Quality & Style

  1. Words.ts Refactor: The change from "heroes" to "tools" theme is fine, but this seems unrelated to the inspector fix. Consider whether this belongs in a separate PR for cleaner history.

  2. Removed Vendor Files: The removal of rivetkit-actor.tgz and rivetkit-core.tgz (-6 lines total) suggests dependency cleanup. Ensure these aren't needed elsewhere.

  3. Missing Tests: No test files were modified or added. Given this is a bug fix for critical functionality, consider adding integration tests to prevent regression.

🔧 Suggested Improvements

  1. Add error boundary handling for worker initialization failures
  2. Add JSDoc comments for the new Meta interface in actor-worker-container.ts
  3. Consider extracting the inspector client creation logic to a shared utility since it's complex
  4. Add logging for successful token resolution to aid debugging

❓ Questions

  1. What was the root cause of the inspector not working? Was it missing tokens, incorrect headers, or both?
  2. Have you tested this with both cloud and engine app types?
  3. Are there any breaking changes for existing actor implementations?

Summary

Overall, this is a solid fix that addresses the core issue. The main concerns are around error handling robustness and ensuring proper cleanup. The changes are well-structured, but would benefit from additional error handling and tests.

Recommendation: Address the error handling issues before merging, particularly in the worker initialization and API response handling.

Sign up for free to 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.

2 participants