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 25, 2025 9:23am
2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
rivet-cloud Ignored Ignored Oct 25, 2025 9:23am
rivet-site Ignored Ignored Preview Oct 25, 2025 9:23am

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..
  • Oct 25, 9:24 AM UTC: NathanFlurry added this pull request to the Graphite merge queue.
  • Oct 25, 9:25 AM UTC: CI is running for this pull request on a draft pull request (#3262) due to your merge queue CI optimization settings.
  • Oct 25, 9:26 AM UTC: Merged by the Graphite merge queue via draft PR: #3262.

@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.

@jog1t jog1t mentioned this pull request Oct 24, 2025
@NathanFlurry NathanFlurry force-pushed the 10-20-fix_make_inspector_working_again branch from 0ebaae2 to fe4da15 Compare October 25, 2025 09:19
@NathanFlurry NathanFlurry force-pushed the 10-24-fix_fe_bring_back_ts_type_check branch from 8e03002 to 0d55d94 Compare October 25, 2025 09:19
@claude
Copy link

claude bot commented Oct 25, 2025

Pull Request Review: Fix Inspector Functionality

Summary

This PR fixes the actor inspector functionality by properly handling authentication tokens, fixing state mutations, and refactoring the words list. Overall, this is a solid bug fix PR with good attention to detail.

Code Quality & Best Practices

✅ Strengths

  1. Proper Token Handling - The refactoring to pass engineToken through the data provider chain is clean and properly propagates async token resolution:

    const token = async () => {
        const response = await queryClient.fetchQuery(
            parent.accessTokenQueryOptions({ namespace }),
        );
        return response.token;
    };
  2. Type Safety Improvements - Added proper type annotations for mutation returns:

    return (await response.json()) as {
        state: unknown;
        enabled: boolean;
    };
  3. Defensive Programming - Good null-safe handling in multiple places:

    Object.keys(args.headers || {}).forEach((key) => {
        if (key.toLowerCase().startsWith("x-fern-")) {
            delete args.headers?.[key];
        }
    });
  4. Mutation Improvement - Changed from mutate to mutateAsync in actor-editable-state.tsx:87 to properly wait for the mutation to complete before updating UI state.

⚠️ Issues & Concerns

1. Potential Race Condition in Token Resolution (Medium Priority)

In actor-worker-container.ts:144-147, the token is resolved during worker setup:

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

Issue: If the token function is async and takes time, this could delay worker initialization. Also, if the token expires during a long session, there's no mechanism to refresh it.

Recommendation: Consider implementing token refresh logic or document the expected token lifetime.

2. Missing Error Handling in Worker (Medium Priority)

In actor-repl.worker.ts:210-216, when the API call fails, the error handling returns either JSON or text:

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

Issue: This silently swallows errors and returns the error as a result, which might be confusing.

Recommendation: Throw a proper error or ensure the error is properly typed and handled.

3. Optional Chaining with Delete (Low Priority)

In engine-data-provider.tsx:54:

delete args.headers?.[key];

Issue: While this works, it's a bit unusual to use optional chaining with delete. If args.headers is undefined, the delete won't do anything anyway.

Recommendation: Consider simplifying to:

if (args.headers && key.toLowerCase().startsWith("x-fern-")) {
    delete args.headers[key];
}

4. Global Variable Check (Low Priority)

In waitForClerk.ts:38:

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

Issue: The check typeof Plain !== "undefined" followed by Plain?. is redundant.

Recommendation: Choose one approach:

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

5. Removed Unused Imports (Good)

Multiple files have unused imports removed (e.g., cloud-data-provider.tsx), which is excellent cleanup.

Performance Considerations

  1. Token Resolution Performance - The async token resolution happens during worker initialization. If this is slow, it could impact user experience. Consider caching or pre-fetching tokens.

  2. Words Array Size Reduction - The massive reduction in the words arrays (from ~1300 to ~151 items) is great for bundle size. This should noticeably improve initial load performance.

Security Concerns

⚠️ Token Exposure in Worker

The worker receives sensitive tokens:

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

Concern: Workers run in a separate context and tokens are passed via postMessage. While this is generally safe, ensure:

  1. The worker is properly terminated when not needed (✅ handled in terminate())
  2. Tokens are not logged or exposed in error messages (⚠️ could be improved)

Recommendation: Audit console.error and console.log statements to ensure tokens aren't accidentally logged.

🔒 Missing Input Validation

The runner field from the actor data is used directly:

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

If runner is undefined, this passes an empty string. Ensure this is handled gracefully on the backend.

Test Coverage

Missing: This PR has no test files for the actor inspector functionality. Given the complexity of the token handling and worker communication:

Recommendations:

  1. Add unit tests for ActorWorkerContainer state management
  2. Add integration tests for token resolution in different scenarios
  3. Add tests for error handling in callAction
  4. Consider E2E tests for the full inspector workflow

Additional Observations

📝 Minor Issues

  1. Empty PR Description - The PR has no description explaining the context or what was broken. This makes it harder for reviewers to understand the motivation.

  2. Commented Code (in original file):

    // FIXME(RVT-4553)
    // if (actor.resources.cpu !== 125 || actor.resources.memory !== 128) {
    //     throw new Error("Unsupported actor resources");
    // }

    Consider tracking this in a separate issue if not already done.

  3. Environment Variable Order Change - In connect-railway-frame.tsx:179-181, the order of env variables changed (swapped RivetNamespaceEnv and RivetTokenEnv). Ensure this doesn't affect functionality.

Verdict

Approve with Minor Recommendations

This PR successfully fixes the inspector functionality with solid implementation. The main concerns are around error handling and test coverage, but none are blocking. The security considerations are worth reviewing, but the current implementation appears safe.

Priority Action Items:

  1. Add test coverage for critical paths (token handling, worker communication)
  2. Improve error handling in worker error responses
  3. Add PR description explaining what was broken and how this fixes it

Review conducted following repository conventions from CLAUDE.md

@claude
Copy link

claude bot commented Oct 25, 2025

Code Review for PR #3229: Fix Inspector

Summary

This PR fixes the inspector functionality by improving the actor worker initialization, token handling, and authentication flow. The changes are generally well-structured and address the core issues. Here are my findings:


Positive Aspects

  1. Improved Token Management: The refactoring to pass engineToken as a function that can be async is a good design choice, allowing for lazy token fetching.

  2. Better Type Safety: Added proper TypeScript types for the response from useActorStatePatchMutation (lines 62-65 in actor.ts).

  3. Defensive Programming: Added typeof Plain !== "undefined" check in waitForClerk.ts to prevent runtime errors when Plain is not available.

  4. Simplified Word Lists: The massive reduction in words.ts (1292 lines deleted!) improves bundle size and performance.

  5. Structured Clone for Security: Using structuredClone(data) in the worker initialization prevents reference issues.


🔍 Issues & Concerns

1. Security: Token Exposure in Worker ⚠️

Location: frontend/src/components/actors/worker/actor-repl.worker.ts:117

The init object now contains sensitive tokens that are stored in the worker's global scope:

let init: null | Omit<InitMessage, "type"> = null;

This includes engineToken, inspectorToken, and namespace information. While workers have isolated scope, this could be a concern if:

  • The worker is compromised by malicious code execution
  • Debug tools expose worker state

Recommendation: Consider clearing tokens from memory when not in use, or implementing a token refresh mechanism rather than storing them long-term.


2. Error Handling: Silent Failures ⚠️

Location: frontend/src/components/actors/worker/actor-repl.worker.ts:210-216

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

This error handling returns error data directly without throwing, which means the calling code won't know if the action failed. The REPL will display the error as a "result" rather than an error.

Recommendation: Either throw an error here or ensure the response format distinguishes between success and error states so the UI can handle it appropriately.


3. Race Condition Risk ⚠️

Location: frontend/src/components/actors/worker/actor-worker-container.ts:122-152

The #setupWorker method is marked as async and awaits this.#meta?.engineToken() before posting the init message. However, there's no guarantee that this.#meta hasn't changed during the await:

async #setupWorker(worker: Worker) {
    this.#worker = worker;
    // ... event listeners ...
    this.#worker.postMessage({
        // ... 
        engineToken:
            typeof this.#meta?.engineToken === "function"
                ? await this.#meta?.engineToken()  // Race condition here
                : this.#meta?.engineToken,
        // ...
    } satisfies InitMessage);
}

Recommendation: Capture this.#meta in a local variable at the start of the method to prevent potential issues if terminate() is called concurrently.


4. Missing Null Checks ⚠️

Location: frontend/src/components/actors/worker/actor-worker-context.tsx:68

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

If runner is undefined/null, this passes an empty string to useInspectorToken, which then tries to query with an empty runner name. This could lead to unnecessary API calls or errors.

Recommendation: Add a conditional to only call useInspectorToken when runner is defined, or handle the empty string case in the hook.


5. Inconsistent Import Organization

Location: Multiple files

The PR removes unused imports in some places (e.g., cloud-data-provider.tsx) but the codebase guideline states:

Always add imports at the top of the file inside of inline within the function.

Some imports are still being added inline or aren't properly organized.

Recommendation: Ensure all imports are at the top of files per the CLAUDE.md guidelines.


🎯 Best Practices & Code Quality

Good:

  • ✅ Proper use of structuredClone for deep copying
  • match from ts-pattern for type-safe conditional logic
  • ✅ Using satisfies for type validation without losing inference

Could Improve:

  • The __APP_TYPE__ global usage in actor-repl.worker.ts line 196 - ensure this is properly defined in the build configuration
  • Consider extracting the inspector client creation logic to a shared utility function since it's duplicated logic

🧪 Testing

No test files were modified in this PR. Given that this fixes broken functionality, consider:

  1. Adding integration tests for the worker initialization flow
  2. Testing token refresh scenarios
  3. Verifying error handling in the REPL

📊 Performance Considerations

Positive Impact:

  • The word list reduction (~1164 lines removed) significantly reduces bundle size
  • Using function-based token fetching allows for lazy evaluation

Potential Concerns:

  • The async token fetching in #setupWorker could delay worker initialization
  • Multiple queries in useInspectorToken might cause unnecessary re-renders

🔒 Security Summary

  1. ⚠️ Token storage in worker memory - Consider token lifecycle management
  2. ⚠️ Error responses might expose stack traces - Ensure error messages are sanitized
  3. Authorization headers properly set - Good use of Bearer tokens
  4. Type checking on message schemas - Using Zod validation

📝 Recommendations Summary

High Priority:

  1. Fix error handling in callAction to properly throw errors
  2. Add null checks for runner before calling useInspectorToken
  3. Prevent race conditions in #setupWorker by capturing this.#meta locally

Medium Priority:
4. Add tests for the inspector functionality
5. Consider token cleanup in worker memory
6. Extract shared inspector client creation logic

Low Priority:
7. Organize imports per codebase guidelines
8. Add JSDoc comments to complex worker logic


Overall Assessment

This is a good fix that restores inspector functionality with improved architecture. The main concerns are around error handling and potential race conditions, but these are addressable. The reduction in bundle size is a nice bonus.

Recommendation: ✅ Approve with suggestions - The issues identified are not blockers but should be addressed in follow-up improvements.

🤖 Generated with Claude Code

@claude
Copy link

claude bot commented Oct 25, 2025

Pull Request Review: Fix Inspector

Summary

This PR fixes the inspector functionality by updating authentication token handling, improving RPC action calls, and refactoring the word list for random key generation. The changes span data providers, worker contexts, and the REPL worker implementation.


✅ Strengths

  1. Better Token Management: The extraction of the token function into a reusable variable improves code clarity and reduces duplication in cloud-data-provider.tsx.

  2. Comprehensive Context Passing: The addition of engineToken, namespace, runnerName, and inspectorToken to worker contexts provides better configuration flexibility.

  3. Improved Error Handling: The worker now properly handles both success and error responses from action calls (lines 210-218 in actor-repl.worker.ts).

  4. Inspector Token Integration: Good separation of concerns with the useInspectorToken hook using pattern matching for different app types.


🔍 Issues & Concerns

Critical Issues

  1. Async Function Without Await (actor-worker-container.ts:122)

    async #setupWorker(worker: Worker) {

    The function is marked async and awaits this.#meta?.engineToken(), but the caller on line 88 doesn't await it:

    this.#setupWorker(worker);  // Missing await!

    Impact: The worker might not be fully initialized before the function returns, leading to race conditions.
    Fix: Add await on line 88.

  2. Removed Vendor Files

    -frontend/vendor/rivetkit-actor.tgz
    -frontend/vendor/rivetkit-core.tgz

    Impact: This could break builds if these packages aren't available via npm/registry.
    Verification Needed: Confirm these packages are available from a package registry.

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

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

    If runner is undefined, an empty string is passed. The useInspectorToken hook then tries to query with an empty runner name, which may cause unnecessary API calls or errors.
    Fix: Consider early return or conditional rendering when runner is not available.

Medium Severity Issues

  1. Inconsistent Error Response Handling (actor-repl.worker.ts:210-218)

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

    This returns the raw error without throwing, which may lead to confusing behavior where errors appear as successful results.
    Recommendation: Consider throwing an error or wrapping in a result type.

  2. Type Safety Concern (actor-worker-context.tsx:42)

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

    Using as string bypasses type checking. If inspectorToken isn't a string, this could cause runtime issues.
    Fix: Add proper type guards or validate the type.

  3. Plain Undefined Check Missing (waitForClerk.ts:38)

    if (typeof Plain !== "undefined") {

    Good defensive check added, but Plain should be properly typed as an optional global.

  4. Mutation State Management (actor-editable-state.tsx:87)
    Changed from mutate to mutateAsync with await, but there's no error handling for the async operation.

    await mutateAsync(JSON.parse(value || ""));
    setIsEditing(false);
    setValue(null);

    Fix: Wrap in try-catch to handle mutation failures gracefully.

Low Severity Issues

  1. Large Word List Replacement
    The PR removes 1,292 lines of superhero names and replaces them with a much smaller, curated list of adjectives and tools. While this makes the code more maintainable:

    • The new list is significantly smaller (less variety)
    • The naming scheme changed from "adjective-hero" to "adjective-tool"

    Question: Was this intentional? The reduced variety might lead to more naming collisions.

  2. Console Logging (actor-worker-container.ts:92)

    console.log(e);

    Should use structured logging with tracing or at minimum console.error for errors per CLAUDE.md guidelines.

  3. Missing Line Numbers in Tracing
    Per CLAUDE.md, log messages should use structured logging:

    // Current
    console.error("Actor Worker Error", msg);
    
    // Should be
    tracing.error(?msg, "actor worker error");

🔒 Security Considerations

  1. Token Exposure: Tokens are passed through worker messages. Ensure workers are from the same origin and can't be intercepted.

  2. Authorization Header: The inspector token is passed in headers. Verify this is transmitted over HTTPS only.

  3. No Token Validation: The code doesn't validate token format before using it. Consider adding basic validation.


🧪 Test Coverage

Issue: No test files found for the modified actor components.

Recommendation: Add tests covering:

  • Token resolution logic (sync/async functions)
  • Worker initialization and error states
  • RPC action calls with various response types
  • Edge cases (missing runner, undefined tokens, etc.)

📊 Performance Considerations

  1. Token Function Calls: The engineToken function may be called multiple times. Consider memoization if it's expensive.

  2. Query Dependencies (actor-worker-context.tsx:108-118): The useEffect has 9 dependencies, which means it will re-run frequently. Consider using useMemo for stable references.

  3. Unnecessary Re-renders: The structuredClone on line 117 of actor-repl.worker.ts might be expensive. Verify if deep cloning is necessary.


📋 Code Quality Recommendations

  1. Add TypeScript Strict Checks: Use proper type narrowing instead of type assertions
  2. Error Boundaries: Consider adding error boundaries around worker components
  3. Consistent Imports: Some files have unused imports that should be cleaned up
  4. Documentation: Add JSDoc comments for the new token handling logic

✅ Action Items

Must Fix Before Merge:

  • Add await to #setupWorker call on line 88 of actor-worker-container.ts
  • Verify vendor packages are available from package registry
  • Add error handling for mutateAsync in actor-editable-state.tsx

Should Fix:

  • Add null/undefined guards for runner in useInspectorToken
  • Replace console.log/error with structured logging per CLAUDE.md
  • Remove type assertions and use proper type guards
  • Handle error responses properly in callAction

Nice to Have:

  • Add unit tests for worker initialization
  • Add tests for token resolution
  • Document the word list change reasoning
  • Consider memoization for expensive token functions

Overall Assessment

Rating: ⚠️ Needs Work

The PR makes good progress on fixing the inspector, with solid architectural improvements around token handling and context passing. However, there are critical async/await issues and missing error handling that should be addressed before merging. The removal of vendor files also needs verification to avoid breaking the build.

Once the critical items are addressed, this will be a solid improvement to the codebase.

@graphite-app graphite-app bot changed the base branch from 10-24-fix_fe_bring_back_ts_type_check to graphite-base/3229 October 25, 2025 09:24
@claude
Copy link

claude bot commented Oct 25, 2025

Code Review: Fix Inspector Functionality

Summary

This PR fixes the actor inspector by addressing authentication and data flow issues. The changes primarily focus on:

  • Properly passing inspector tokens and engine tokens through the data provider chain
  • Fixing the actor REPL worker to make authenticated API calls
  • Cleaning up imports and fixing type issues
  • Simplifying the words list (significant line reduction)

Code Quality & Best Practices

✅ Strengths

  1. Proper Token Handling: The PR correctly threads authentication tokens through multiple layers:

    • engineToken is now properly exposed in data providers (engine-data-provider.tsx:70)
    • Inspector token is retrieved conditionally based on app type (actor-worker-context.tsx:29-44)
  2. Type Safety Improvements:

    • useActorStatePatchMutation now properly types the response (actor.ts:62-66)
    • Async mutation properly awaited before state updates (actor-editable-state.tsx:87)
  3. Cleaner Code:

    • Removed unused imports (cloud-data-provider.tsx:3-4)
    • Extracted token function to avoid duplication (cloud-data-provider.tsx:342-348)

⚠️ Issues & Concerns

1. Missing parent Variable (Critical Bug)
Location: engine-data-provider.tsx:431

engineToken: parent.engineToken,

The parent variable is not defined in the createNamespaceContext function scope. This should reference the passed-in parameter from the function signature. This will cause a runtime error.

Fix needed:

export const createNamespaceContext = ({
	namespace,
	client,
+	...parent  // Need to destructure parent properties
}: { namespace: string; } & ReturnType<typeof createGlobalContext>) => {

2. Unsafe Header Deletion
Location: 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 null check is unnecessary
	}
});

The || {} check ensures headers is never null/undefined, so args.headers?.[key] should just be args.headers[key]. The optional chaining is misleading here.

3. Error Handling in Worker
Location: actor-repl.worker.ts:210-216

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

This swallows the actual error response. Consider:

  • Throwing an error instead of returning the error response
  • Logging the error for debugging
  • Providing structured error information

4. Console Logging in Production Code
Locations: actor-worker-container.ts:92, actor-worker-container.ts:135, actor-worker-container.ts:243

console.log(e);  // Line 92
console.log(error, error.message, error.error);  // Line 135
console.error("Actor Worker Error", msg);  // Line 243

While debugging logs are sometimes acceptable, consider:

  • Using a proper logging library with log levels
  • Using structured logging with tracing (per CLAUDE.md guidelines)
  • Example: tracing::info!(?e, "worker initialization failed") pattern

5. Defensive Guard Type Check
Location: actor-worker-context.tsx:68

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

Calling the hook with an empty string when runner is undefined may trigger unnecessary queries. Consider:

  • Conditionally calling the hook or adding proper enabled checks
  • Or ensure the hook properly handles empty strings without making API calls

Performance Considerations

  1. Token Refetching: The token function in cloud-data-provider.tsx:342 calls fetchQuery each time. This is good for freshness but verify caching is configured correctly (15-minute staleTime is set at line 310).

  2. Words List Optimization: Excellent reduction from 1292 to 151 entries (88% reduction). This significantly reduces bundle size.

  3. UseEffect Dependencies: The exhaustive deps list in actor-worker-context.tsx:108-118 is correct and properly documented with biome-ignore. Good practice.

Security Concerns

  1. Token Exposure in Headers:

    • Tokens are passed via headers which is correct
    • Inspector token uses Bearer auth (line 187-189)
    • Engine token uses custom header X-Rivet-Token (line 199)
    • Ensure these are only sent over HTTPS in production
  2. Function Constructor Usage
    Location: actor-repl.worker.ts:73-81

return new Function(
	"window",
	...argsString,
	`"use strict";
        return (async () => {
            ${jsCode.value}
    })()
    `,
)({}, ...argValues);

Using new Function() with user code has security implications. While this appears to be for REPL functionality (which inherently executes user code), ensure:

  • This runs in a sandboxed web worker (✅ it does)
  • The worker has restricted permissions
  • Input is properly validated/sanitized

Test Coverage

Missing Tests: The PR doesn't include any test changes. Consider adding tests for:

  • Token passing through data provider layers
  • Inspector token retrieval logic based on app type
  • Error handling in the REPL worker
  • State patch mutation response handling

Additional Observations

  1. Railway Environment Variables Order Change
    connect-railway-frame.tsx:179-182: The order of env vars changed (namespace and token swapped). Verify this matches the expected order in Railway's integration.

  2. Plain Undefined Check
    waitForClerk.ts:38: Good defensive check for Plain object existence before calling it.

  3. Missing Runner Field
    default-data-provider.tsx:314: The runner field is now included in the actor data transformation. Ensure the API actually returns this field consistently.

  4. Query Key Changes
    engine-data-provider.tsx:194: The query key was changed from { namespace, namespaceId } to just { namespace }. This changes cache behavior - verify this is intentional and won't cause cache invalidation issues.

Recommendations

  1. Fix the critical parent undefined bug immediately ⚠️
  2. Add unit tests for the authentication flow
  3. Consider using structured logging instead of console.log
  4. Document the inspector token flow for future maintainers
  5. Add error boundaries around the worker container
  6. Consider extracting magic strings (header names) to constants

Verdict

This PR makes important fixes to get the inspector working, but has one critical bug that must be fixed before merging. The authentication flow improvements are well-designed, but the missing parent variable will cause runtime errors.

Recommendation: Request changes to fix the critical bug, then approve after verification.


Review generated with attention to Rivet's coding standards from CLAUDE.md

graphite-app bot pushed a commit that referenced this pull request Oct 25, 2025
@graphite-app graphite-app bot closed this Oct 25, 2025
@graphite-app graphite-app bot deleted the 10-20-fix_make_inspector_working_again branch October 25, 2025 09:26
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