Skip to content

[BUG] Tables and custom operations not found when mocks are imported into a named workspace #12

@pr0head

Description

@pr0head

Description

When importing a config file into a named workspace via mockd workspace use <id> + mockd import <file>, mocks receive the correct workspaceId, but statefulResources (tables) and customOperations are always registered under the empty/default workspace "".
As a result, when a matched mock (with WorkspaceID = "A") tries to resolve its stateful table or custom operation, lookups fail with StatusNotFound because neither StateStore.Get nor Bridge.executeCustom fall back to the default workspace.

Steps to Reproduce

  1. Create a config file exchange-a.yaml with mocks, tables, and custom operations:
mocks:
  - id: place-order
    type: http
    http:
      matcher:
        method: POST
        path: /orders
      statefulBinding:
        table: orders
        action: create

statefulResources:
  - name: orders
    idField: id

customOperations:
  - name: CancelOrder
    steps:
      - action: delete
        resource: orders
        id: "{{input.orderId}}"
  1. Start mockd and create a workspace:
mockd start
mockd workspace create -n exchange-a
mockd workspace use <exchange-a-id>
mockd import exchange-a.yaml
  1. Call the mock:
curl -X POST http://localhost:4280/orders -d '{"symbol":"BTC"}'
  1. Call a custom operation endpoint bound to CancelOrder.

Expected Behavior

  • POST /orders creates an item in the orders table and returns 201.
  • Custom operation CancelOrder executes successfully.

Actual Behavior

  • POST /orders returns 404StateStore.Get("exchange-a-id", "orders") returns nil
    because the table is registered under workspace "", not "exchange-a-id".
  • Custom operation returns 404Bridge.executeCustom looks up
    b.customOps["exchange-a-id"]["CancelOrder"], finds nothing, and has no fallback.

Environment

  • OS: Windows 11
  • Go Version: 1.25.0
  • mockd Version: v0.6.4
  • Installation Method: Docker

Configuration

# exchange-a.yaml
mocks:
  - id: place-order
    type: http
    http:
      matcher:
        method: POST
        path: /orders
      statefulBinding:
        table: orders
        action: create

statefulResources:
  - name: orders
    idField: id

customOperations:
  - name: CancelOrder
    steps:
      - action: delete
        resource: orders
        id: "{{input.orderId}}"

Logs

# Expected after POST /orders:
404 No mock matched the request  ← or stateful resource not found

Additional Context

There are two possible solutions to this issue:

  1. Fallback to the default workspace
  2. Specify the workspace when importing resources (as is done for mocks)
Criterion Fallback Explicit workspaceId
Complexity Less code More code
Clarity Implicit Explicit — better for debugging
Error risk May hide a typo in the table/operation name Error is immediately apparent
Backward compatibility Works for configs without workspaceId Requires configuration update
Data isolation None (different workspaces may accidentally see each other's tables) Full isolation

I can help you fix the issue if you confirm it and select your preferred solution.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions