Fix FlutterFlow's api_calls.dart 'Target of URI' Error
You moved your WidgetChat HTTP request out of a widget and into a Custom Action so you could send a message, await the reply, and return clean text to your chat UI. Then FlutterFlow's editor lit up red:
Target of URI doesn't exist: '/backend/api_requests/api_calls.dart'. Try creating the file referenced by the URI, or try using a URI for a file that does exist.
Compile blocked. Test mode stuck. Here's the good news: the file exists and your code is correct. This is a well-known false positive from FlutterFlow's in-editor analyzer, and the fix is a single line.
Why the analyzer is wrong
FlutterFlow generates lib/backend/api_requests/api_calls.dart dynamically, at project build/export time. But the Dart analyzer that powers the Custom Code panel runs against a partial snapshot of your project where that generated file hasn't been materialized yet. The import resolves to nothing, so you get Target of URI doesn't exist.
Once FlutterFlow actually compiles or exports the project, the file is there and the import binds fine. The red squiggle is an analysis-time artifact, not a real compile error — you just have to tell the analyzer to stop flagging that one line.
The one-line fix
Add a Dart // ignore comment directly above the import:
// ignore: uri_does_not_exist
import '/backend/api_requests/api_calls.dart';
That // ignore: uri_does_not_exist directive suppresses exactly this analyzer rule for the next line only. The import still works at compile time; you've just muted the premature warning.
Two details people get wrong:
- Use the leading-slash path
'/backend/api_requests/api_calls.dart'. That slash is FlutterFlow's package-root shorthand. Do not use a relative../../backend/...path — that genuinely won't resolve. - Place the import below the auto-generated block. When FlutterFlow assembles the file it hoists any
importlines you write to the top, so putting it in the "Begin custom action code" region is fine.
Naming: the generated Call class
Inside api_calls.dart, FlutterFlow generates one class per API call, named from the call's display name in CamelCase + a Call suffix, and you invoke its static .call(...).
So if you define an API call named SendChatMessage in the API Calls tab (a POST to your WidgetChat endpoint), the generated class is SendChatMessageCall, and every variable you declared on that call becomes a named argument:
final response = await SendChatMessageCall.call(
apiKey: apiKey,
message: message,
sessionId: sessionId,
);
That returns an ApiCallResponse. The properties you'll use most:
succeeded(bool?) — HTTP-level successjsonBody(dynamic) — parsed JSON responsebodyText(String) — raw bodystatusCode(int) — HTTP status
To pull a single field out of jsonBody, use getJsonField(...) with a JSONPath. It lives in flutter_flow_util.dart, which FlutterFlow auto-imports, so no extra import is needed.
Copy-paste WidgetChat Custom Action
Create a Custom Action named sendWidgetChatMessage, mark it async with a return type of String, add three String arguments (apiKey, message, sessionId), and paste this:
// Automatic FlutterFlow imports
import '/backend/schema/structs/index.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
// This single line clears the false "Target of URI" error:
// ignore: uri_does_not_exist
import '/backend/api_requests/api_calls.dart';
Future<String> sendWidgetChatMessage(
String apiKey,
String message,
String sessionId,
) async {
// Call the generated API class. API call "SendChatMessage"
// => class SendChatMessageCall.
final ApiCallResponse response = await SendChatMessageCall.call(
apiKey: apiKey,
message: message,
sessionId: sessionId,
);
// Network/HTTP failure -> friendly fallback for the chat bubble.
if (!(response.succeeded ?? false)) {
return 'Sorry, I could not reach support right now. Please try again.';
}
// WidgetChat replies with { "reply": "..." }.
final reply = getJsonField(response.jsonBody, r'''$.reply''');
return reply?.toString() ?? '';
}
The moment you add the // ignore line, the red error on api_calls.dart disappears from the editor and Test/Run mode compiles.
Wire it into your chat UI
On your send button's action chain:
- Custom Action →
sendWidgetChatMessage, passing your WidgetChatapiKey, the TextField value asmessage, and a storedsessionId(so the bot keeps conversational context). - Store the returned String in a page-state list of messages, or append it to your chat
ListView's data source. - Clear the input field.
Because the action returns a plain String, you never touch raw JSON in the UI builder — the parsing stays in Dart where it belongs.
Still red after it compiles? Checklist
If the error survives an actual compile (not just the editor), it's no longer the false positive — check these:
- The comment is exactly
// ignore: uri_does_not_exist, immediately above the import, no blank line between. - The import path starts with a slash:
'/backend/api_requests/api_calls.dart'. - The class name matches your API call name:
SendChatMessage→SendChatMessageCall. A typo here is a real "undefined name" error, not the URI one. - The API call is actually defined in the API Calls tab. If nothing in your app references it, FlutterFlow can tree-shake it and the generated class won't exist. Referencing it once (even from this action) keeps it in the build.
- You didn't rename the auto-imports or delete the
DO NOT REMOVEblock.
Try WidgetChat free
WidgetChat drops an AI customer-support chatbot into your Flutter or FlutterFlow app with a real REST endpoint you can call exactly like the action above — send a message, get a grounded reply, keep session context. Try WidgetChat free and have your in-app support bot answering questions today.





Comments
Comments are coming soon. We'd love to hear your thoughts!