Skip to content

Batch sub-request URLs incompatible with FileMaker OData #207

@chriscors

Description

@chriscors

Bug

db.batch() fails with FileMaker OData's $batch endpoint because sub-request URLs inside the multipart body use an incorrect format.

Root Cause

Two issues in formatSubRequest() (src/client/batch-request.ts, line 32):

lines.push(`${request.method} ${fullUrl} HTTP/1.1`);
  1. Otto proxy prefix (/otto/) is included — The _getBaseUrl() returns https://host/otto/fmi/odata/v4, so sub-request URLs contain /otto/.... Once inside the batch body, FileMaker's OData engine processes the sub-requests directly and doesn't understand the /otto/ prefix. This produces: {"code": "-1000", "message": "Incorrect OData service root path"}

  2. Database name includes .fmp12 extension — The database name in the URL includes the file extension (e.g. GMT_Web.fmp12), but FileMaker's batch processor expects it without the extension (e.g. GMT_Web). This produces: {"code": "-1032", "message": "Operation database does not match batch request database"}

What Works

Sub-request URLs must use the canonical FileMaker OData path format:

GET /fmi/odata/v4/{database_name_WITHOUT_fmp12}/{table}?$query HTTP/1.1

Tested and confirmed working:

POST https://host/otto/fmi/odata/v4/GMT_Web.fmp12/$batch  ← outer request (through Otto proxy)

Sub-request inside batch body:
GET /fmi/odata/v4/GMT_Web/bookings?$top=1&$select=_GMTNum HTTP/1.1  ← no /otto/, no .fmp12

Response: HTTP/1.1 200 Ok with correct data.

Tested and failing:

Sub-request URL format Error
https://host/otto/fmi/odata/v4/GMT_Web.fmp12/bookings (current) -1000 Incorrect OData service root path
/otto/fmi/odata/v4/GMT_Web.fmp12/bookings -1000 Incorrect OData service root path
/fmi/odata/v4/GMT_Web.fmp12/bookings -1032 Operation database does not match
bookings (bare table name) -1000 Incorrect OData service root path
GMT_Web.fmp12/bookings -1000 Incorrect OData service root path

Suggested Fix

In formatSubRequest() (or formatBatchRequestFromNative), transform each sub-request URL before writing it into the multipart body:

  1. Strip the Otto proxy prefix (everything before /fmi/)
  2. Strip the .fmp12 extension from the database name segment
  3. Use an absolute path (starting with /fmi/odata/v4/...), not the full https://... URL

Something like:

function toBatchSubRequestUrl(fullUrl: string): string {
  const url = new URL(fullUrl);
  // Strip otto prefix: /otto/fmi/... → /fmi/...
  const path = url.pathname.replace(/^\/otto/, '');
  // Strip .fmp12 extension from database name
  const batchPath = path.replace(/\.fmp12/, '');
  return `${batchPath}${url.search}`;
}

Additional Note

The boundary parsing also required proper \r\n line endings throughout the multipart body. The current implementation handles this correctly via formatBatchRequestFromNative.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions