Observability/Logs/Explorer: Error: Cannot parse datasources from saved object

When attempting to experiment with the observability dashboard/logs and event viewer, I am seeing lots of errors. The console has many examples of “[] is not a valid term at this part of the query: ‘source = ’ <– HERE” and I am unable to do things like reorder columns. Initially i see this error:

Versions (relevant - OpenSearch/Dashboard/Server OS/Browser):

{
  "name": "opensearch-node1",
  "cluster_name": "docker-cluster",
  "cluster_uuid": "3csuJbfxSJ2MMsRgLiFT4Q",
  "version": {
    "distribution": "opensearch",
    "number": "3.0.0",
    "build_type": "tar",
    "build_hash": "dc4efa821904cc2d7ea7ef61c0f577d3fc0d8be9",
    "build_date": "2025-05-03T06:25:26.379676844Z",
    "build_snapshot": false,
    "lucene_version": "10.1.0",
    "minimum_wire_compatibility_version": "2.19.0",
    "minimum_index_compatibility_version": "2.0.0"
  },
  "tagline": "The OpenSearch Project: https://opensearch.org/"
}

Describe the issue:

I’m using the observability plugins of the dashboard for the first time, and getting logs of errors from background requests failing. they looks like this

:5601/api/ppl/search:1 
 Failed to load resource: the server responded with a status of 400 (Bad Request)

observabilityDashboards.plugin.js:185 fetch error:  Object error :  "Bad Request" message :  "{\n  \"error\": {\n    
\"reason\": \"Invalid Query\",\n    \"details\": \"[<EOF>] is not a valid term at this part of the query: 'source = ' <-- HERE. Expecting one of 323 possible tokens. Some examples: 'SEARCH', 'DESCRIBE', 'SHOW', 'FROM', 'WHERE', ...\",\n    \"type\": \"SyntaxCheckException\"\n  },\n  \"status\": 400\n}"
statusCode
:  400 [[Prototype]] :  Object constructor: ƒ Object()

Configuration:

Using standard docker-compose build mostly with defaults. (I’ve been trying various options to fix problems)

name: opensearch_dashboard

services:
  opensearch-node1:
    image: opensearchproject/opensearch:latest
    container_name: opensearch-node1
    environment:
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - node.name=opensearch-node1
      - OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g
      - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD}
      # - plugins.security.disabled=true
      - plugins.ml_commons.only_run_on_ml_node=false
      - plugins.query.datasources.encryption.masterkey="${OPENSEARCH_MASTERKEY}"
    ulimits:
      memlock:
        soft: -1 # Set memlock to unlimited (no soft or hard limit)
        hard: -1
      nofile:
        soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
        hard: 65536
    volumes:
      - opensearch-data1:/usr/share/opensearch/data # Creates volume called opensearch-data1 and mounts it to the container
    ports:
      - 9200:9200 # REST API
      - 9600:9600 # Performance Analyzer
    networks:
      - opensearch-net # All of the containers will join the same Docker bridge network

  opensearch-dashboards:
    image: opensearchproject/opensearch-dashboards:latest
    container_name: opensearch-dashboards
    ports:
      - 5601:5601 # Map host port 5601 to container port 5601
    expose:
      - "5601" # Expose port 5601 for web access to OpenSearch Dashboards
    environment:
      - OPENSEARCH_HOSTS=["https://opensearch-node1:9200"]
      - DISABLE_SECURITY_DASHBOARDS_PLUGIN=true
      - APPLICATION_CONFIG_ENABLED=true
    networks:
      - opensearch-net

  vector:
    image: timberio/vector:latest-debian
    container_name: vector
    volumes:
      - ./vector.yaml:/etc/vector/vector.yaml:ro
    depends_on:
      - opensearch-node1
    ports:
      - "8686:8686" # HTTP sink (optional)
      - "28080:8080" # Expose vector status API
    networks:
      - opensearch-net


volumes:
  opensearch-data1:

networks:
  opensearch-net:

Relevant Logs or Screenshots:

I’m not permitted to upload logs according to the message i just got so:

window.onload @ bootstrap.js:116
10:07:43.425 observabilityDashboards.plugin.js:185 fetch error:  {statusCode: 400, error: 'Bad Request', message: '{\n  "error": {\n    "reason": "Invalid Query",\n    …e": "SyntaxCheckException"\n  },\n  "status": 400\n}'}
(anonymous) @ observabilityDashboards.plugin.js:185
Promise.catch
(anonymous) @ observabilityDashboards.plugin.js:185
fetchEvents @ observabilityDashboards.plugin.js:129

its posting this

{"query":"source = ","format":"jdbc"}
POST /api/ppl/search HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 37
Content-Type: application/json
Cookie: ph_phc_t3lgBB66QsPW4HEfiGopO14u...JcVK8mfZ6MvwST5DwzzyWY
Host: docker.lan:5601
Origin: http://docker.lan:5601
Pragma: no-cache
Referer: http://docker.lan:5601/app/observability-logs
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36
osd-version: 3.0.0
osd-xsrf: osd-fetch

and getting this back

{
    "statusCode": 400,
    "error": "Bad Request",
    "message": "{\n  \"error\": {\n    \"reason\": \"Invalid Query\",\n    \"details\": \"[<EOF>] is not a valid term at this part of the query: 'source = ' <-- HERE. Expecting one of 323 possible tokens. Some examples: 'SEARCH', 'DESCRIBE', 'SHOW', 'FROM', 'WHERE', ...\",\n    \"type\": \"SyntaxCheckException\"\n  },\n  \"status\": 400\n}"
}

it seems like this

export function QueryArea({
  tabId,
  handleQueryChange,
  handleTimePickerChange,
  handleTimeRangePickerRefresh,
  runQuery,
  tempQuery,
  setNeedsUpdate,
  runChanges,
  selectedIndex,
  nlqInput,
  setNlqInput,
  pplService,
}: any) {
  const requestParams = { tabId };
  const { getAvailableFields } = useFetchEvents({
    pplService,
    requestParams,
  });

  // use effect that sets the editor text and populates sidebar field for a particular index upon initialization
  const memoizedGetAvailableFields = useMemo(() => getAvailableFields, []);
  const memoizedHandleQueryChange = useMemo(() => handleQueryChange, []);
  useEffect(() => {
    const indexQuery = `source = ${selectedIndex[0]?.label || ''}`;
    memoizedHandleQueryChange(indexQuery);
    memoizedGetAvailableFields(indexQuery);
  }, [selectedIndex, memoizedGetAvailableFields, memoizedHandleQueryChange]);
  const [lastFocusedInput, setLastFocusedInput] = useState<'query_area' | 'nlq_input'>('nlq_input');
  const [callOut, setCallOut] = useState<React.ReactNode>(null);

so it seem to be trying to pull the selectedIndex from state, which doesn’t have it

https://github.com/opensearch-project/dashboards-observability/blob/main/public/components/common/search/search.tsx#L561