Can we access your project?
Current Behavior
Actual: The generated CreateScanCall.call() method accepts firebaseUid/title as named arguments but never uses them — it calls ApiManager.makeApiCall(..., params: {}, ...) with a hardcoded empty map regardless of what's passed in. The uploaded file is captured into _model.uploadedLocalFile_scanImageUploadCamera but is never referenced anywhere else — CreateScanCall.call() has no file parameter at all. Net result: the network request goes out with no fields and no file.
Expected Behavior
Expected: Tapping "Take Photo"/"Choose from Library" captures/picks an image, uploads it, and sends it to the CreateScan endpoint along with the firebase_uid and title text fields, all as multipart form parts — per your support reply, this should work by declaring the file parameter as Value Source = From Variable, type Uploaded File, bound to the UploadData action's output.
Separately: the DSL-level fix you described isn't reachable through your own public SDK. The binding you're asking for requires varFromWidgetState(type: FFWidgetStateVariable_ActionVariableType.UPLOAD_DATA, actionKeyRef: ...) (confirmed this exists and is the correct mechanism at the proto level), but that helper — along with varFromAuthUser, varFromPageState, etc. — lives in lib/src/helpers/variable_helpers.dart, which is exported only from lib/src/internal_sdk.dart, not from the public package:flutterflow_ai/flutterflow_ai.dart barrel that agent-authored DSL scripts (dsl/edit.dart) actually import. So there's currently no supported way to author this binding from the public DSL surface at all, even though flutterflow ai docs api-surface documents varFromWidgetState as if it were part of the agent-facing contract.
Steps to Reproduce
Reproduction steps:
- Declare a multipart POST endpoint with 1+ non-file variables/body fields (e.g. firebase_uid, title).
- On a button, chain UploadData(destination: UploadDestination.localFile, actionName: 'x') immediately followed by ApiCall(thatEndpoint, params: {...}) — the pattern documented in your own references/rest_graphql_api_dsl.dart "UploadAvatar" example.
- Run flutterflow ai run to push (validates and compiles cleanly — no errors).
- Inspect the generated Dart in generated_code/lib/backend/api_requests/api_calls.dart and the calling page's widget file — both the declared params and the uploaded file are dropped from the actual network call.
Reproducing run/commit ID: BbflOtMScFvC3mKzZr4o (project doc-uscanner-jbqfhi, FlutterFlow AI SDK 0.0.40, build b5c8a09d)
Generated code snippet (generated_code/lib/backend/api_requests/api_calls.dart):
class CreateScanCall {
Future call({
String? firebaseUid = '',
String? title = '',
}) async {
final baseUrl = DocUscannerScansGroup.getBaseUrl();
return ApiManager.instance.makeApiCall(
callName: 'CreateScan',
apiUrl: '${baseUrl}/scans',
callType: ApiCallType.POST,
headers: {},
params: {}, // <-- firebaseUid/title args never land here
bodyType: BodyType.MULTIPART,
returnBody: true,
encodeBodyUtf8: false,
decodeUtf8: false,
cache: false,
isStreamingApi: false,
alwaysAllowBody: false,
);
}
}
Generated code snippet (generated_code/lib/add_scan_page/add_scan_page_widget.dart, call site):
safeSetState(() {
_model.uploadedLocalFile_scanImageUploadCamera = selectedUploadedFiles.first;
});
// ... file captured above is never referenced again ...
apiUrl: '${baseUrl}/scans',
callType: ApiCallType.POST,
headers: {},
params: {}, // <-- firebaseUid/title args never land here
bodyType: BodyType.MULTIPART,
returnBody: true,
encodeBodyUtf8: false,
decodeUtf8: false,
cache: false,
isStreamingApi: false,
alwaysAllowBody: false,
);
}
}
Generated code snippet (generated_code/lib/add_scan_page/add_scan_page_widget.dart, call site):
safeSetState(() {
_model.uploadedLocalFile_scanImageUploadCamera = selectedUploadedFiles.first;
});
// ... file captured above is never referenced again ...
_model.createdScanFromCamera = await DocUscannerScansGroup.createScanCall.call(
firebaseUid: currentUserUid, // passed in, but ignored inside .call()
title: _model.title,
);
// .call() has no parameter to receive the uploaded file at all
DSL that produced it (dsl/edit.dart):
final createScan = Endpoint.post(
'CreateScan',
'/scans',
variables: {'firebase_uid': string, 'title': string},
body: const {'firebase_uid': '<firebase_uid>', 'title': '<title>'},
bodyType: HttpBodyType.multipart,
);
app.apiGroup(
'DocUscanner Scans',
baseUrl: 'https://x8ki-letl-twmt.n7.xano.io/api:docuscanner-scans',
endpoints: [createScan],
);
// TakePhotoButton onTap:
onTap: [
const UploadData(
source: UploadSource.camera,
allowPhoto: true,
destination: UploadDestination.localFile,
actionName: 'scanImageUploadCamera',
),
ApiCall(
createScan,
params: {
'firebase_uid': const AuthUser(AuthUserField.userId),
'title': State('title'),
},
outputAs: 'createdScanFromCamera',
onSuccess: (_) => [Snackbar('Scan saved'), const NavigateBack()],
onFailure: [Snackbar('Failed to save scan')],
),
],
Reproducible from Blank
Bug Report Code (Required)
IT4olMmAxItIrsNa7aqNbPlahSQUHEA3U7gVkspBZywgfZzzBLN/fPfQPxFBcO3kTQhbfVqmp14K0tLLkd7qV/ZeEzSWft1Nyc8JbTrhUj6RVJuTF7qgOGtDP59mIX6457W3vSZ4APdqSF4tw061ft+vVhLcO4zJDXowSq/LZO4=
Visual documentation
No Images to be shared
Environment
FlutterFlow version:
- FlutterFlow AI SDK (CLI/DSL pipeline used to reproduce this): 0.0.40 (build b5c8a09d)
- FlutterFlow web editor version: I don't have this — this bug was reproduced entirely through the CLI (flutterflow ai run) and a local iOS simulator run, never through the browser-based editor at app.flutterflow.io. If they need the editor's own version number, you'd find it in the app.flutterflow.io editor itself (usually under the account/help menu) — I have no visibility into that from here.
Platform:
- Reproduced via: FlutterFlow AI CLI (flutterflow / flutterflow ai commands) driving a local Flutter build, plus FlutterFlow Desktop for the local run/simulator session. Not reproduced through the web editor.
Browser name and version:
- Not applicable — no browser was involved in reproducing this.
Operating system and version affected:
- macOS 26.2 (build 25C56), Darwin 25.2.0, arm64 (Apple Silicon)
- Simulator target: iOS 26 (iPhone 17 simulator) via Xcode/CocoaPods build — Dart 3.12.2
Additional Information
Bug report: multipart ApiCall drops body variables and uploaded file in generated Dart
Environment
- FlutterFlow AI SDK version: 0.0.40 (build b5c8a09d)
- Dart: 3.12.2
- API base: https://api.flutterflow.io/v2
- Project ID: doc-uscanner-jbqfhi
- Reproducing commit/run ID: BbflOtMScFvC3mKzZr4o (2026-08-09T15:01:55Z)
Summary
Declaring an Endpoint.post(..., bodyType: HttpBodyType.multipart) with variables:/body:, then calling it via ApiCall(...) immediately after an UploadData(...) action in the same trigger chain, produces generated Dart that silently drops both the declared body variables and the uploaded file — the network request goes out empty.
FlutterFlow's own validator already flags this — the run's diagnostics include (as a non-blocking warning, so it didn't stop the push):
[warning] R11: API call action on a page with form fields but no widget state bindings detected in action configuration
This fired twice (once per button) on AddScanPage, which has a TextField (title) and two buttons that each chain UploadData → ApiCall. The R11 check appears to detect exactly this failure mode but is only a warning rather than a hard validation error.
DSL that produced it (dsl/edit.dart):
final createScan = Endpoint.post(
'CreateScan',
'/scans',
variables: {'firebase_uid': string, 'title': string},
body: const {'firebase_uid': '<firebase_uid>', 'title': '<title>'},
bodyType: HttpBodyType.multipart,
);
app.apiGroup(
'DocUscanner Scans',
baseUrl: 'https://x8ki-letl-twmt.n7.xano.io/api:docuscanner-scans',
endpoints: [createScan],
);
// ... inside AddScanPage, on TakePhotoButton:
onTap: [
const UploadData(
source: UploadSource.camera,
allowPhoto: true,
destination: UploadDestination.localFile,
actionName: 'scanImageUploadCamera',
),
ApiCall(
createScan,
params: {
'firebase_uid': const AuthUser(AuthUserField.userId),
'title': State('title'),
},
outputAs: 'createdScanFromCamera',
onSuccess: (_) => [Snackbar('Scan saved'), const NavigateBack()],
onFailure: [Snackbar('Failed to save scan')],
),
],
Generated code — actual (broken), generated_code/lib/backend/api_requests/api_calls.dart:
class CreateScanCall {
Future call({
String? firebaseUid = '',
String? title = '',
}) async {
final baseUrl = DocUscannerScansGroup.getBaseUrl();
return ApiManager.instance.makeApiCall(
callName: 'CreateScan',
apiUrl: '${baseUrl}/scans',
callType: ApiCallType.POST,
headers: {},
params: {}, // <-- always empty; firebaseUid/title args unused
bodyType: BodyType.MULTIPART,
returnBody: true,
...
);
}
}
And the call site, generated_code/lib/add_scan_page/add_scan_page_widget.dart:
_model.uploadedLocalFile_scanImageUploadCamera = selectedUploadedFiles.first;
// ... file is captured but never referenced again ...
_model.createdScanFromCamera = await DocUscannerScansGroup.createScanCall.call(
firebaseUid: currentUserUid, // <-- passed in here, but ignored inside .call()
title: _model.title,
);
// no file argument exists on .call() at all
Expected: ApiManager.makeApiCall's multipart path (multipartRequest(...) in api_manager.dart) already separates file-valued vs. non-file entries out of its params map, so the generator should be populating params with both the bound text fields (firebase_uid, title) and the uploaded file (_model.uploadedLocalFile_scanImageUploadCamera) — matching how the same params mechanism correctly threads through for JSON/x-www-form-urlencoded endpoints (verified working via the SDK's own references/rest_graphql_api_dsl.dart "CreatePost" example, which is JSON-bodied).
Confirmed not a client-side DSL/SDK-compiler bug: compiler.dart's _compileApiCallNode correctly builds the FFApiCallValue bindings into the pushed proto (verified by reading .flutterflow/sdk/flutterflow_ai/lib/src/dsl/compiler.dart and ui/actions.dart). The proto sent to FlutterFlow's backend is correct; the defect is in FlutterFlow's server-side proto→Dart codegen specifically for multipart-bodied ApiCall actions.
Repro steps for FlutterFlow's team:
- Declare a multipart POST endpoint with 1+ text variables/body fields.
- On a button, chain UploadData(destination: UploadDestination.localFile, actionName: 'x') → ApiCall(thatEndpoint, params: {...}).
- Push, then inspect the generated .call() method and its call site — the file and declared params are both dropped from the actual network call.
Can we access your project?
Current Behavior
Actual: The generated CreateScanCall.call() method accepts firebaseUid/title as named arguments but never uses them — it calls ApiManager.makeApiCall(..., params: {}, ...) with a hardcoded empty map regardless of what's passed in. The uploaded file is captured into _model.uploadedLocalFile_scanImageUploadCamera but is never referenced anywhere else — CreateScanCall.call() has no file parameter at all. Net result: the network request goes out with no fields and no file.
Expected Behavior
Expected: Tapping "Take Photo"/"Choose from Library" captures/picks an image, uploads it, and sends it to the CreateScan endpoint along with the firebase_uid and title text fields, all as multipart form parts — per your support reply, this should work by declaring the file parameter as Value Source = From Variable, type Uploaded File, bound to the UploadData action's output.
Separately: the DSL-level fix you described isn't reachable through your own public SDK. The binding you're asking for requires varFromWidgetState(type: FFWidgetStateVariable_ActionVariableType.UPLOAD_DATA, actionKeyRef: ...) (confirmed this exists and is the correct mechanism at the proto level), but that helper — along with varFromAuthUser, varFromPageState, etc. — lives in lib/src/helpers/variable_helpers.dart, which is exported only from lib/src/internal_sdk.dart, not from the public package:flutterflow_ai/flutterflow_ai.dart barrel that agent-authored DSL scripts (dsl/edit.dart) actually import. So there's currently no supported way to author this binding from the public DSL surface at all, even though flutterflow ai docs api-surface documents varFromWidgetState as if it were part of the agent-facing contract.
Steps to Reproduce
Reproduction steps:
Reproducing run/commit ID: BbflOtMScFvC3mKzZr4o (project doc-uscanner-jbqfhi, FlutterFlow AI SDK 0.0.40, build b5c8a09d)
Generated code snippet (generated_code/lib/backend/api_requests/api_calls.dart):
class CreateScanCall {
Future call({
String? firebaseUid = '',
String? title = '',
}) async {
final baseUrl = DocUscannerScansGroup.getBaseUrl();
return ApiManager.instance.makeApiCall(
callName: 'CreateScan',
apiUrl: '${baseUrl}/scans',
callType: ApiCallType.POST,
headers: {},
params: {}, // <-- firebaseUid/title args never land here
bodyType: BodyType.MULTIPART,
returnBody: true,
encodeBodyUtf8: false,
decodeUtf8: false,
cache: false,
isStreamingApi: false,
alwaysAllowBody: false,
);
}
}
Generated code snippet (generated_code/lib/add_scan_page/add_scan_page_widget.dart, call site):
safeSetState(() {
_model.uploadedLocalFile_scanImageUploadCamera = selectedUploadedFiles.first;
});
// ... file captured above is never referenced again ...
apiUrl: '${baseUrl}/scans',
callType: ApiCallType.POST,
headers: {},
params: {}, // <-- firebaseUid/title args never land here
bodyType: BodyType.MULTIPART,
returnBody: true,
encodeBodyUtf8: false,
decodeUtf8: false,
cache: false,
isStreamingApi: false,
alwaysAllowBody: false,
);
}
}
Generated code snippet (generated_code/lib/add_scan_page/add_scan_page_widget.dart, call site):
safeSetState(() {
_model.uploadedLocalFile_scanImageUploadCamera = selectedUploadedFiles.first;
});
// ... file captured above is never referenced again ...
_model.createdScanFromCamera = await DocUscannerScansGroup.createScanCall.call(
firebaseUid: currentUserUid, // passed in, but ignored inside .call()
title: _model.title,
);
// .call() has no parameter to receive the uploaded file at all
DSL that produced it (dsl/edit.dart):
final createScan = Endpoint.post(
'CreateScan',
'/scans',
variables: {'firebase_uid': string, 'title': string},
body: const {'firebase_uid': '<firebase_uid>', 'title': '<title>'},
bodyType: HttpBodyType.multipart,
);
app.apiGroup(
'DocUscanner Scans',
baseUrl: 'https://x8ki-letl-twmt.n7.xano.io/api:docuscanner-scans',
endpoints: [createScan],
);
// TakePhotoButton onTap:
onTap: [
const UploadData(
source: UploadSource.camera,
allowPhoto: true,
destination: UploadDestination.localFile,
actionName: 'scanImageUploadCamera',
),
ApiCall(
createScan,
params: {
'firebase_uid': const AuthUser(AuthUserField.userId),
'title': State('title'),
},
outputAs: 'createdScanFromCamera',
onSuccess: (_) => [Snackbar('Scan saved'), const NavigateBack()],
onFailure: [Snackbar('Failed to save scan')],
),
],
Reproducible from Blank
Bug Report Code (Required)
IT4olMmAxItIrsNa7aqNbPlahSQUHEA3U7gVkspBZywgfZzzBLN/fPfQPxFBcO3kTQhbfVqmp14K0tLLkd7qV/ZeEzSWft1Nyc8JbTrhUj6RVJuTF7qgOGtDP59mIX6457W3vSZ4APdqSF4tw061ft+vVhLcO4zJDXowSq/LZO4=
Visual documentation
No Images to be shared
Environment
Additional Information
Bug report: multipart ApiCall drops body variables and uploaded file in generated Dart
Environment
Summary
Declaring an Endpoint.post(..., bodyType: HttpBodyType.multipart) with variables:/body:, then calling it via ApiCall(...) immediately after an UploadData(...) action in the same trigger chain, produces generated Dart that silently drops both the declared body variables and the uploaded file — the network request goes out empty.
FlutterFlow's own validator already flags this — the run's diagnostics include (as a non-blocking warning, so it didn't stop the push):
[warning] R11: API call action on a page with form fields but no widget state bindings detected in action configuration
This fired twice (once per button) on AddScanPage, which has a TextField (title) and two buttons that each chain UploadData → ApiCall. The R11 check appears to detect exactly this failure mode but is only a warning rather than a hard validation error.
DSL that produced it (dsl/edit.dart):
final createScan = Endpoint.post(
'CreateScan',
'/scans',
variables: {'firebase_uid': string, 'title': string},
body: const {'firebase_uid': '<firebase_uid>', 'title': '<title>'},
bodyType: HttpBodyType.multipart,
);
app.apiGroup(
'DocUscanner Scans',
baseUrl: 'https://x8ki-letl-twmt.n7.xano.io/api:docuscanner-scans',
endpoints: [createScan],
);
// ... inside AddScanPage, on TakePhotoButton:
onTap: [
const UploadData(
source: UploadSource.camera,
allowPhoto: true,
destination: UploadDestination.localFile,
actionName: 'scanImageUploadCamera',
),
ApiCall(
createScan,
params: {
'firebase_uid': const AuthUser(AuthUserField.userId),
'title': State('title'),
},
outputAs: 'createdScanFromCamera',
onSuccess: (_) => [Snackbar('Scan saved'), const NavigateBack()],
onFailure: [Snackbar('Failed to save scan')],
),
],
Generated code — actual (broken), generated_code/lib/backend/api_requests/api_calls.dart:
class CreateScanCall {
Future call({
String? firebaseUid = '',
String? title = '',
}) async {
final baseUrl = DocUscannerScansGroup.getBaseUrl();
return ApiManager.instance.makeApiCall(
callName: 'CreateScan',
apiUrl: '${baseUrl}/scans',
callType: ApiCallType.POST,
headers: {},
params: {}, // <-- always empty; firebaseUid/title args unused
bodyType: BodyType.MULTIPART,
returnBody: true,
...
);
}
}
And the call site, generated_code/lib/add_scan_page/add_scan_page_widget.dart:
_model.uploadedLocalFile_scanImageUploadCamera = selectedUploadedFiles.first;
// ... file is captured but never referenced again ...
_model.createdScanFromCamera = await DocUscannerScansGroup.createScanCall.call(
firebaseUid: currentUserUid, // <-- passed in here, but ignored inside .call()
title: _model.title,
);
// no file argument exists on .call() at all
Expected: ApiManager.makeApiCall's multipart path (multipartRequest(...) in api_manager.dart) already separates file-valued vs. non-file entries out of its params map, so the generator should be populating params with both the bound text fields (firebase_uid, title) and the uploaded file (_model.uploadedLocalFile_scanImageUploadCamera) — matching how the same params mechanism correctly threads through for JSON/x-www-form-urlencoded endpoints (verified working via the SDK's own references/rest_graphql_api_dsl.dart "CreatePost" example, which is JSON-bodied).
Confirmed not a client-side DSL/SDK-compiler bug: compiler.dart's _compileApiCallNode correctly builds the FFApiCallValue bindings into the pushed proto (verified by reading .flutterflow/sdk/flutterflow_ai/lib/src/dsl/compiler.dart and ui/actions.dart). The proto sent to FlutterFlow's backend is correct; the defect is in FlutterFlow's server-side proto→Dart codegen specifically for multipart-bodied ApiCall actions.
Repro steps for FlutterFlow's team: